JavaScript数据结构—— 单向链表
JavaScript数据结构(三) 单向链表
认识链表
链表与数组的区别
数组
- 数组相邻的元素之间空间是连续的
- JavaScript提供了许多处理数组的方法
- 对经常用下标来操作时候,数组的效率会比链表高
链表
- 相邻的元素之间空间是可能是不连续的
- 对元素经常要删除和插入,相对数组链表的操作效率要高
- 访问链表内的元素,都要从链表的表头一个一个开始找。
链表图示
地址
为对象的引用
链表中的常见操作
append(element)
向链表尾部添加一个新的项。insert(position, element)
向链表的特定位置插入一个新的项。get(position)
获取对应位置的元素。indexOf(element)
返回元素在链表中的索引。如果链表中没有该元素就返回-1。update(position, element)
修改某个位置的元素。removeAt(position)
从链表的特定位置移除一项。remove(element)
从链表中移除一项。isEmpty()
如果链表中不包含任何元素,返回 trun,如果链表长度大于 0 则返回 false。size()
返回链表包含的元素个数,与数组的 length 属性类似。toString()
由于链表项使用了 Node 类,就需要重写继承自 JavaScript 对象默认的 toString 方法,让其只输出元素的值
JS代码封装单向链表操作
class Node {
constructor(data) {
this.item = data;
this.next = null;
}
}
class LinkedList {
constructor() {
this.head = null;
this.length = 0;
}
append(element) {
const node = new Node(element);
if (!this.head) {
this.head = node;
} else {
let current = this.head;
while (current.next) {
current = current.next;
}
current.next = node;
}
this.length += 1;
}
insert(position, element) {
if (position < 0 || position > this.length + 1) {
return false
}
const node = new Node(element);
if (position == 0) {
node.next = this.head;
this.head = node;
} else {
let index = 0;
let current = this.head;
while (index < position - 1) {
index++;
current = current.next;
}
node.next = current.next;
current.next = node;
}
this.length += 1;
}
get(position) {
if (position < 0 || position > this.length) {
return false
}
let index = 0;
let current = this.head;
while (index < position) {
index += 1;
current = current.next;
}
return current.item;
}
indexOf(element) {
let current = this.head;
let index = 0;
while (current) {
if (current.item == element) {
return index
} else {
index += 1;
current = current.next;
}
}
return -1
}
update(position, element) {
if (position < 0 || position > this.length) {
return false
}
let index = 0;
let current = this.head;
while (index < position) {
index += 1;
current = current.next;
}
current.item = element;
return current.item
}
removeAt(position) {
if (position < 0 || position > this.length) {
return false
}
let index = 0;
let current = this.head;
if (position == 0) {
this.head = this.head.next;
this.length -= 1
return current.item;
}
while (index < position - 1) {
index += 1;
current = current.next;
}
const deleteNode = current.next;
current.next = current.next.next;
this.length -= 1
return deleteNode.item;
}
remove(element) {
const index = this.indexOf(element);
const deleteNode = this.removeAt(index);
return deleteNode
}
isEmpty() {
return this.length == 0;
}
size() {
return this.length
}
toString() {
let result = '';
let current = this.head;
while (current) {
result += current.item + ' ';
current = current.next;
}
return result;
}
}
//测试代码
const linkedList = new LinkedList();
linkedList.append(111);
linkedList.append(222);
linkedList.append(333);
console.log(linkedList.toString());//111 222 333
linkedList.insert(0, 444)
linkedList.insert(2, 555)
console.log(linkedList.toString());//444
console.log(linkedList.get(1));// 111
console.log(linkedList.indexOf(55));// -1
console.log(linkedList.update(1, 999));// 999
console.log(linkedList.removeAt(0)); // 444
console.log(linkedList.toString());// 999 555 222 333
console.log(linkedList.remove(555));// 555
console.log(linkedList.toString());// 999 222 333
console.log(linkedList.isEmpty());// false
console.log(linkedList.size());// 3
onsole.log(linkedList.remove(555));// 555
console.log(linkedList.toString());// 999 222 333
console.log(linkedList.isEmpty());// false
console.log(linkedList.size());// 3