2021年4月19日星期一

前端数据结构--线性结构-链表

链表

  标准数组是一块连续的内存地址,所以在做插入、删除时会对数据进行大量的移动,如果数据量很大那么效率会比较低。如果我们把每一个元素都记录着下一个元素的地址,那我们在做插入、删除时是不是只需要改变下一个元素的地址即可, 如

 从存储结构来看链表不需要一块连续的内存空间,它通过"指针"将一组零散的内存块串联起来使用 

 常见的链表结构有单链表、双向链表、循环链表、双向循环链表。

单链表

  链表中的每一个节点都具备两个功能:一个功能是存储数据,另外一个功能是记录下一个节点的地址。当结点只记录下一个结点的地址且最后一个结点指向null,这种链表叫单链表。

循环链表

  循环链表是一种特殊的单链表。它跟单链表的区别就在尾结点。单链表的尾结点指针指向null 空地址,表示这是最后的结点,而循环链表的尾结点指针是指向链表的头结点 如

双向链表

  单链表只有一个方向,结点只有一个指向后面结点的指针,双向链表支持两个方向,一个是前面,一个是后面 如

双向循环链表

  把循环链表、双向链表组合就是双向循环链表,结点可以指向前面、后面结点的指针,同时尾结点还指向了头结点 如

 数组与链表

数组与链表是两种不同的内存组织方式,数组的特点是随机访问、内存地址连续,插入、删除操作不需要移动元素。链表结点要保存上一个结点、下一个结点的信息(对内存的消耗比较大),对于插入、删除操作只需要改变引用的指针即可。

 js 实现单链表

 1 /* 2  数据是1:1的关系 3  单向链表:只有指向一个方向 4  循环链表:末尾节点指向头部节点(跟节点)  5  双向链表:节点存在指向上、下节点的引用 6  双向循环链表:把循环链表、双向链表组合而成 7 */ 8  9 class Node {10  constructor (data) {11  this.data = data12  this.next = null13  }14 }15 16 class linkedList {17  constructor () {18  this.header = null19  this.size = 020  }21 // 插入末尾22  append (data) {23  const addNode = new Node(data)24  if (!this.header) {25  this.header = addNode26  } else {27  const currNode = this.find()28  currNode.next = addNode29  }30  this.size++31  }32 // 插入到x位置,其中是x索引从0开始33  insertAt (index, data) {34  if (index < 0 || index > this.size) {35  throw new Error('插入的位置不正确')36  }37  const node = new Node(data)38  if (index === 0) {39  node.next = this.header40  this.header = node41  } else {42  let pre = this.getNode(index - 1)43  node.next = pre.next44  pre.next = node45  }46  this.size++47  }48 // 删除49  remove (index) {50  if (index < 0 || index >= this.size) {51  throw new Error('超出链表索引')52  }53  54  if (index === 0) {55  this.header = this.header.next56  } else {57  const pre = this.getNode(index - 1)58  const delNode = pre.next59  pre.next = delNode.next60  }61  this.size--62  }63 // 通过索引获取64  getNode (index) {65  if (index < 0 || index >= this.size) {66  throw new Error('超出链表索引')67  }68  let currentNode = this.header69  for (let i = 0; i < index; i++) {70  currentNode = currentNode.next71  }72  return currentNode73  }74 // 获取末尾节点75  find () {76  let currentNode = this.header77  while (currentNode.next) {78  currentNode = currentNode.next79  }80 return currentNode81  }82 }83 84 const linkList = new linkedList()85 linkList.append('header')86 linkList.append(1)87 linkList.append(2)88 linkList.append(3)89 linkList.insertAt(4, 4)90 linkList.insertAt(3, '3-before') // 插入到3的前面91 92 linkList.remove(4)93 console.log(linkList)

对链表的插入、删除操作,在插入第一个结点和删除最后一个结点的情况,需要进行特殊处理,即空链。

预览 codepen

 









原文转载:http://www.shaoqun.com/a/695754.html

跨境电商:https://www.ikjzd.com/

亚马逊全球开店:https://www.ikjzd.com/w/1299

oklink:https://www.ikjzd.com/w/1362


链表  标准数组是一块连续的内存地址,所以在做插入、删除时会对数据进行大量的移动,如果数据量很大那么效率会比较低。如果我们把每一个元素都记录着下一个元素的地址,那我们在做插入、删除时是不是只需要改变下一个元素的地址即可,如从存储结构来看链表不需要一块连续的内存空间,它通过"指针"将一组零散的内存块串联起来使用常见的链表结构有单链表、双向链表、循环链表、双向循环链表。单链表  链表中的每一个节点都具
eprice:https://www.ikjzd.com/w/1325
amazon go:https://www.ikjzd.com/w/67
乐宝:https://www.ikjzd.com/w/2200
环金科技:https://www.ikjzd.com/w/1072
英国脱欧热潮下,eBay建议英国站卖家做好这些准备!:https://www.ikjzd.com/home/106831
听听多年亚马逊经验的卖家谈选品:https://www.ikjzd.com/home/16548

没有评论:

发表评论