数据结构与算法之链表
Posted simpul
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法之链表相关的知识,希望对你有一定的参考价值。
链表
JS中数组被实现成了对象,对比其他语言的数组效率很低。因此可以考虑使用链表来替代。除了对数据的随机访问,链表几乎可以用在任何使用以为数组的情况中。如果需要随机访问,数组仍然是更好的选择。
单向链表
链表是由一组节点组成的集合。 每个节点都使用一个对象的引用指向它的后继。 指向另一
个节点的引用叫做链。
遍历链表, 就是跟着链接, 从链表的首元素一直走到尾元素,下面最前面的节点叫做头节点,在最后面的尾元素指向一个null节点。
// 节点类
function Node(element)
this.element = element;
this.next = null;
// LinkedList类,建立一个新的链表
function LList()
this.head = new Node("head");
LList.prototype =
constructor: LList,
find(element)
var node = this.head;
while(node.element != element)
if(node.next)
node = node.next;
else
return null;
return node;
,
insert(newElement, item) //在item后面插入新元素
var current = this.find(item);
var newNode = new Node(newElement);
newNode.next = current.next;
current.next = newNode;
,
remove(item)
var preNode = this.findPrevious(item);
if(preNode.next !== null)
preNode.next = preNode.next.next;
,
display() //不显示头节点
var current = this.head;
while(current.next !== null)
console.log(current.next.element);
current = current.next;
,
findPrevious(item) //用来查找该值节点的前一个节点
var current = this.head;
while(current.next.element !== item)
if(current.next !== null)
current = current.next;
else
return null;
return current;
双向链表
// 节点类
function Node(element)
this.element = element;
this.next = null;
this.previous = null;
// LinkedList类,建立一个新的链表
function LList()
this.head = new Node("head");
LList.prototype =
constructor: LList,
find(element)
var node = this.head;
while(node.element != element)
if(node.next)
node = node.next;
else
return null;
return node;
,
insert(newElement, item) //在item后面插入新元素
var current = this.find(item);
var newNode = new Node(newElement);
newNode.next = current.next;
newNode.previous = current;
current.next = newNode;
,
remove(item) //双向链表删除节点效率更高了,因为不需要再查找前驱节点了
var removeNode = this.find(item);
if(removeNode)
removeNode.previous.next = removeNode.next;
removeNode.next.previous = removeNode.previous;
removeNode.next = null;
removeNode.previous = null;
,
display() //不显示头节点
var current = this.head;
while(current.next !== null)
console.log(current.next.element);
current = current.next;
,
findLast() //查找链表的最后一项
var current = this.head;
while(current.next !== null)
current = current.next;
return current;
,
dispReverse()
var current = this.findLast();
while(current.previous !== null)
console.log(current.element);
current = current.previous;
,
循环链表
循环链表和单向链表相似, 节点类型都是一样的。 唯一的区别是, 在创建循环链表时, 让其头节点的 next 属性指向它本身,这样插入节点都会使得链表的尾节点都指向头节点,形成一个循环链表。
如果你希望可以从后向前遍历链表, 但是又不想付出额外代价来创建一个双向链表, 那么就需要使用循环链表。 从循环链表的尾节点向后移动, 就等于从后向前遍历链表。
避免无限循环,需要对方法进行修改:
// 节点类
function Node(element)
this.element = element;
this.next = null;
// LinkedList类,建立一个新的链表
function LList()
this.head = new Node("head");
this.head.next = this.head;
LList.prototype =
constructor: LList,
find(element)
var node = this.head;
while(node.element != element)
if(node.next === this.head)
return null;
node = node.next;
return node;
,
insert(newElement, item) //在item后面插入新元素
var current = this.find(item);
var newNode = new Node(newElement);
newNode.next = current.next;
current.next = newNode;
,
remove(item)
var preNode = this.findPrevious(item);
preNode.next = preNode.next.next;
,
display() //不显示头节点
var current = this.head;
while(current.next !== this.head)
console.log(current.next.element);
current = current.next;
,
findPrevious(item) //用来查找该值节点的前一个节点
var current = this.head;
while(current.next.element !== item)
if(current.next === this.head)
return null;
current = current.next;
return current;
以上是关于数据结构与算法之链表的主要内容,如果未能解决你的问题,请参考以下文章