4.链表
-
内存空间不连续,能实现灵活的内存动态管理
-
链表创建时不需确定大小,大小可随需要而扩充
-
在插入和删除数据时,时间复杂度可达到O(1)
4.1链表的火车结构
链表类似于火车,有一个火车头,火车头连接一个节点(车厢),节点(车厢)内有乘客(数据),并且此节点连接下一节点,以此类推
4.2链表的常见操作
-
append(element):向列表尾部添加一个新的项
-
insert(position,element):向列表的特定位置插入一个新的项
-
get(position):获取对应位置的元素
-
indexOf(element):返回元素在列表中的索引,如果列表中没有该元素则返回-1
-
update(positon,element):修改某个位置的元素
-
removeAt(position):从列表的特定位置移除一项
-
remove(element):从列表中移除指定的值
-
isEmpty():如果链表没有元素,返回true,否则返回False
-
size():返回链表包含的元素个数
-
toString():由于列表项使用了Nodeod,就需要重写继承自js对象默认的toString方法,让其只输出元素的值
4.3链表操作的实践
-
链表整体实现预览
function LinkedList () { function Node (data, next) { this.data = data this.next = next } this.head = null this.length = 0//记录当前数组的长度 //append LinkedList.prototype.append = function (element) {} LinkedList.prototype.insert = function (position,element) {} LinkedList.prototype.get = function (position){} LinkedList.prototype.indexOf = function (element){} LinkedList.prototype.update = function (positon,element){} LinkedList.prototype.removeAt = function (position){} LinkedList.prototype.remove = function (element){} LinkedList.prototype.isEmpty = function (){} LinkedList.prototype.size = function (){} LinkedList.prototype.toString = function (){} }
-
append(element)方法实现
向链表尾部追加数据有两种情况
-
链表本身为空,新添加的节点为唯一节点
-
链表不为空,在其他节点后追加节点
LinkedList.prototype.append = function (element) { var newNode = new Node(data) if (this.length == 0)//第一个节点 { this.head = newNode } else { var currentNode = this.head while (currentNode.next != null) {//循环找到最后一个节点 currentNode = currentNode.next } currentNode.next = newNode//将新节点插入 } this.length+=1 }
-
-
insert(position,element)方法实现
在任意位置插入数据
-
添加到第一个位置
表示新添加的节点为头节点,此时需要将原来的头节点,作为新节点的next同时head应该指向该新节点
-
添加到其他位置
-
首先需要通过while循环,从头节点开始去遍历查找新节点需要插入的位置,并且在查找过程中保存上个节点与下个节点
-
当找到正确位置后,将新节点的next指向下一个节点,上一个节点的next指向新节点
-
LinkedList.prototype.insert = function (position, data) { var currentNode = this.head var index = 0 var newNode = new Node(data) if (position < 0 || position > this.length) return false if (position == 0) { this.head = newNode newNode.next = currentNode } else { while (currentNode != null) { if (index++ == position - 1) break else { currentNode = currentNode.next } } var q = currentNode.next currentNode.next = newNode newNode.next = q } this.length += 1 return true }
-
-
toString()方法实现
LinkedList.prototype.toString = function () { currentNode = this.head let elements = '' while (currentNode != null) { elements += currentNode.data + ' ' currentNode = currentNode.next } return elements }
-
get(position)方法
LinkedList.prototype.get = function (position) { var currentNode = this.head var index = 0 if (position < 0 || position >= this.length) return false else { while (index++ < position) { currentNode = currentNode.next } return currentNode.data } }
-
indexOf(element)方法
LinkedList.prototype.indexOf = function (element) { var currentNode = this.head var index = 0 while (currentNode != null) { if (currentNode.data == element) return index else currentNode = currentNode.next index += 1 } return -1 }
-
removeAt(position)方法
LinkedList.prototype.removeAt = function (position) { var index = 0 var currentNode = this.head if (position < 0 || position >= this.length) return false if (position == 0) this.head = this.head.next else{ while (index+1 < position) { currentNode = currentNode.next index+=1 } currentNode.next = currentNode.next.next } this.length -= 1 return true }
-
update(position,element)方法
LinkedList.prototype.update = function (position, element) { var currentNode = this.head var index = 0 if (position < 0 || position >= this.length) return false while (index++ < position) { currentNode = currentNode.next } currentNode.data = element return true }
-
remove(element)方法
//方法一: LinkedList.prototype.remove = function (element) { var currentNode = this.head var prev = this.head if (this.length == 0) return false if (this.length == 1 && element == currentNode.element) { this.head = null } else { while (currentNode != null) { if (element == currentNode.element) { if (currentNode === this.head) { this.head = currentNode.next} prev.next = currentNode.next break } else { prev = currentNode currentNode = currentNode.next } } } this.length-=1 return true } //方法二 LinkedList.prototype.remove = function (element) { var position = this.indexOf(element) this.removeAt(position) }
-
isempty()方法
LinkedList.prototype.isEmpty = function () { if (this.length == 0) return true else return false }
-
size()方法
LinkedList.prototype.size = function () { return this.length }