单链表
原来的数组结构缺点很多
1、数组通常需要申请一端连续的内存空间,而且大小固定,所以当这个数组不能满足容量要求需要扩容
2、插入成本高
3、虽然JavaScript的Array类可以给我们做这一些事,但背后的原理依然是这样的
链表优点:
1、内存空间不是连续的
2、每一个元素存储元素本身的节点和一个指向下一个元素的引用
3、不必要在创建确定大小,区别数组
4、插入和删除操作效率高,时间复杂度为O(1)
5、但是查找效率低,需要从头访问元素
链表结构: head -> [item, next] -> [item, next] -> null
function LinkedList() {
this.head = null
this.length = 0
function Node(data) {
this.data = data
this.next = null
}
LinkedList.prototype.append = (data) => {
const newNode = new Node(data)
if (this.length === 0) {
this.head = newNode
} else {
let current = this.head
while(current.next) {
current = current.next
}
current.next = newNode
}
this.length += 1
}
LinkedList.prototype.toString = () => {
let listStr = ''
let current = this.head
while(current) {
listStr += current.data + " "
current = current.next
}
return listStr
}
LinkedList.prototype.insert = (position, data) => {
if (position < 0 || position > this.length) {
return false
}
const newNode = new Node(data)
if (position === 0) {
newNode.next = this.head
this.head = newNode
} else {
let index = 0
let current = this.head
let previous = null
while(index++ < position) {
previous = current
current = current.next
}
newNode.next = current
previous.next = newNode
}
this.length += 1
return true
}
LinkedList.prototype.get = (position) => {
if (position < 0 || position >= this.length) {
return null
}
let index = 0
let current = this.head
while(index++ < position) {
current = current.next
}
return current.data
}
LinkedList.prototype.indexOf = (data) => {
let index = 0
let current = this.head
while(current) {
if (current.data === data) {
return index
}
current = current.next
index += 1
}
return -1
}
LinkedList.prototype.update = (position, data) => {
if (position < 0 || position >= this.length) {
return false
}
let current = this.head
let index = 0
while(index++ < position) {
current = current.next
}
current.data = data
return true
}
LinkedList.prototype.removeAt = (position) => {
if (position < 0 || position >= this.length) {
return false
}
if (position === 0) {
let current = this.head
this.head = current.next
} else {
let index = 0
let current = this.head
let previous = null
while(index++ < position) {
previous = current
current = current.next
}
previous.next = current.next
}
this.length -= 1
return true
}
LinkedList.prototype.remove = (data) => {
let index = 0
let current = this.head
while(current) {
if (current.data === data) {
this.removeAt(index)
return true
} else {
current = current.next
index += 1
}
}
return false
}
LinkedList.prototype.isEmpty = () => {
if (this.length > 0) {
return false
} else {
return true
}
}
LinkedList.prototype.size = () => {
return this.length
}
}