JavaScript-链表
《Javascript数据结构与算法》第五章
5.1 链表数据结构
链表差别与数组
- 数组要插进去或许移入一个元素的本钱很高,因为一切元素都须要挪动位置。
- 链表插进去或许挪动一个元素时很高效,因为并不须要挪动其他的元素位置。
链表存储元素的体式格局,在内存中不是有递次的,每个元素由
- 1.存储元素自身的节点
- 2.指向一下元素的指针构成
5.2 建立链表
5.2.0 建立链表的骨架
- 1.链表须要有一个 Node 类,示意要到场链表的项,它包含 2 个部份,一个是该项的值,和一个只想下一项的指针
- 2.链表还须要个示意链表长度的属性 length
- 3.示意第一项的援用 head
- 4.和一系列增编削查、查询长度的要领
function LinkedList() {
function Node(element) {
this.element = element;
this.next = null;
}
this.length = 0;
this.head = null;
this.append = function(element) {};
this.insert = function(position, element) {};
this.remove = function(position) {};
}
5.2.1 append,向链表尾部增加元素
this.append = function(element) {
var node = new Node(element); //此时node实例 {element:'111',next:null}
this.length + 1;
if (this.head === null) {
this.head = node;
} else {
//插进去到末了一项,然则因为没有递次,所以我们没法直接获得链表的末了一项,只能while轮回next为null
let lastNode = head;
while (lastNode.next !== null) {
lastNode = lastNode.next;
}
lastNode.next = node;
}
};
5.2.2 removeAt 从链表中删除元素
思绪就是分 2 个状况
- 假如要删除第 0 项,就把 head 指向 head.next 就好了
- 假如要删除第 n 项,须要 while 轮回找到这当前这个 current 项目,将 current 的前一项的 next,超出 current,指向指向 current 的下一项
如许当前元素被抛弃在计算机内存中,就等着被渣滓接纳机制,本身接纳了。
this.removeAt = function(position) {
// 搜检是不是position参数的边境
if (position > -1 && position < length) {
let current = head,
previous, // 示意position上一项元素
index = 0;
if (position === 0) {
head = current.next;
} else {
// 假如index++,一直到index追上position时,那末这个current就是position索引对应的元素了
while (index++ < position) {
previous = current;
current = current.next;
}
// 让position对应的元素的,上一项的next,超出要删除的这一项,直接指向下一项元素就好了
previous.next = current.next;
}
length--;
return current;
} else {
return null;
}
};
5.2.3 insert 在某个位置插进去
this.insert = function(position, element) {
if (position >= 0 && position < length) {
let node = new Node(element);
let index = 0;
let current = head;
let previous;
if (position === 0) {
node.next = current;
head = node;
} else {
while (index++ < position) {
previous = current;
current = current.next;
}
node.next = current;
previous.next = node;
}
length++;
return true;
} else {
return false;
}
};
5.2.4 toString 打印链表
this.toString = function() {
let current = head;
let str = "";
while (current) {
str += current.element + (current.next ? " - " : "");
current = current.next;
}
return str;
};
5.2.5 size 猎取链表长度
this.size = function() {
return length;
};
双向链表骨架
以上是单向链表的JS完成,实际上链表另有多种差别的范例,比方双向链表、轮回链表
双向链表和单向链表的一个区分在于,每个item,不单单议包含value和next指针,还包含prev指针
同时双向链表不单单议保留head,也保留末了一项的援用。
如许的优点是: 迭代单向链表时,假如错过了某一项,只能从新迭代,然则双向链表就找到上一项
function DoublyLinkedList(){
let Node = function(){
this.element = element;
this.next = null;
this.prev = null; // 指向上一项的指针
}
let length = 0;
let head = null;
let tail = null; // 保留末了一项的索引
}
轮回链表
轮回链表,是指末了一项的指针不是null,而是指向第一个元素的一种链表。
所以轮回链表,有多是单向链表,也多是双向链表
双向轮回链表,末了一项的指针指向head,第一项的指针指向tail