您的位置:首页 > 理论基础 > 数据结构算法

数据结构与算法JavaScript - 链表

2016-07-28 09:24 507 查看
数组不是组织数据的最佳数据结构,js中的数组与其它语言中的数组不同,他被实现成了对象,与其它语言相比,js中的数组效率很低。

如果发现数组效率很低时,我们可以使用链表来代替任何可以使用一维数组的情况,但是如果需要随机访问,数组仍然是最佳选择。

链表

链表是由一组节点组成的集合,每个节点都使用一个对象都引用指向他的后继,指向另一个节点的引用叫做链。

链表元素考相互之间的关系进行引用。

遍历链表,就是跟着链接,从链表的首元素一直走到尾元素(不包含链表的头节点,头节点一般用来作为链表的接入点)

链表的头节点需要特殊标记,链表的尾元素指向一个
null
节点

链表的插入、删除元素功能强大。

单向链表构造函数

// Node 类主要用来表示节点
function Node(element) {
this.element = element;
this.next = null;
}
// LinkedList 类提供了插入节点、删除节点、显示列表元素的方法,以及一些其它辅助方法
function LList() {
this.head = new Node("head");
this.find = find;
this.insert = insert;
this.remove = remove;
this.display = display;
this.findPrevious = findPrevious;
}

function find(item) {
var currNode = this.head;
while(currNode.element !== item) {
currNode = currNode.next;
}
return currNode;
}

function insert(newElement, item) {
var newNode = new Node(newElement);
var current = this.find(item);
newNode.next = current.next;
current.next = newNode;
}

function display() {
var currNode = this.head;
while (!currNode.nex == null) {
print (currNode.next.element);
currNode = currNode.next;
}
}

function findPrevious(item) {
var currNode = this.head;
while (!(currNode.next == null) && (currNode.next.element != item)) {
currNode = currNode.next;
}
return currNode;
}

function remove(item) {
var prevNode = this.findPrevious(item);
if (!(prevNode.next == null)) {
prevNode.next = prevNode.next.next;
}
}


双向链表

使用双向链表,双向链表的构造函数与单向链表大体相同,主要需要修改一下:

function Node(element) {
this.element = element;
this.next = null;
this.previous = null;
}

function LList() {
this.head = new Node("head");
this.find = find;
this.insert = insert;
this.remove = remove;
this.display = display;
this.findLast = findLast;
this.dispReverse = dispReverse;
}

function find(item) {
var currNode = this.head;
while(currNode.element !== item) {
currNode = currNode.next;
}
return currNode;
}
function insert(newElement, item) {
var newNode = new Node(newElement);
var current = this.find(item);
newNode.next = current.next;
newNode.previous = current;
current.next = newNode;
}

function display() {
var currNode = this.head;
while (!currNode.nex == null) {
print (currNode.next.element);
currNode = currNode.next;
}
}

function remove(item) {
var currNode = this.find(item);
if (!(currNode.next == null)) {
currNode.previous.next = currNode.next;
currNode.next.previous = currNode.previous;
currNode.next = null;
currNode.previous = null;
}
}
function findLast() {
var currNode = this.head;
while (!(currNode.next == null)) {
currNode = currNode.next;
}
return currNode;
}
function dispReverse() {
var currNode = this.head;
currNode = this.findLast();
while (!(currNode.previous == null)) {
print(currNode.element);
currNode = currNode.previous;
}
}


循环链表

循环链表与单向链表的区别就是,创建循环链表时,让头节点的next属性指向它本身,从循环链表的尾节点向后移动,就等于从后向前遍历链表

function LList() {
this.head = new Node("head");
this.head.next = this.head;
this.find = find;
this.insert = insert;
this.remove = remove;
this.display = display;
this.findLast = findLast;
this.dispReverse = dispReverse;
}
function display() {
var currNode = this.head;
while (!(currNode.next == null) &&
!(currNode.next.element == "head")) {
print(currNode.next.element);
currNode = currNode.next;
}
}
// 其它循环的更改方法与display()函数相同
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息