JavaScript数据结构基础学习二
JavaScript数据结构基础学习
链表
链表的每一个元素都存储下一个元素的指针位置(单链表)
每一个元素都知道下一个元素,但不知道上一个元素
使用原因
- 可以有效的调整大小并在列表的开头和结尾插入
- 如果需要频繁 在头部插入数据,链表比数组性能更高(链表是无序的且不连续的)
- 数组静态分配内存,链表动态分配内存
链表&数组时间复杂度
链表 | 数组 | |
---|---|---|
元素访问 | O(n) | O(1) |
末尾插入 | O(1)[定义了尾部标记,否则是O(n)] | O(1) |
头部插入 | O(1) | O(n) |
中间插入 | O(n) | O(n) |
元素搜索 | O(n) | O(n) |
链表代码简单实现
class LinkedList{
constructor(){
this.head = null
this.tail = null
}
//append 追加节点,末尾追加
append(value){
const newNode = {value:value,next:null}
if(this.tail){
this.tail.next = newNode;//更新关联
}
this.tail = newNode // 更新末尾节点
if(!this.head){
this.head = newNode
}
}
//prepend 前置节点 头部添加
prepend(value){
const newNode = {value:value,next:this.head}
this.head = newNode
if(!this.tail){
this.tail = newNode
}
}
// delete 删除节点
delete(value){
if(!this.head){
return new Error("链表为空")
}
while(this.head &&this.head.value === value){
this.head = this.head.next
return true
}
let curNode = this.head;
while(curNode.next){
if(curNode.next.value === value){
curNode.next = curNode.next.next
return true
}else{
curNode = curNode.next
}
}
if(this.tail.value === value){
this.tail = curNode
return true
}
return false
}
// find 节点查询
find(value){
if(!this.head){
return null
}
let curNode = this.head
while(curNode){
if(curNode.value === value){
return curNode
}
curNode = curNode.next
}
return null
}
// insertAfter 在某个节点后面插入
insertAfter(value,afterValue){
const existingNode = this.find(afterValue)
if(existingNode){
const newNode = {value:value,next:existingNode.next}
exisitingNode.next = newNode
}
}
// 删除头部节点
deleteHead(){
if(!this.head){
return null
}
const deleteHead = this.head
if(this.head.next){
this.head = this.head.next
}else{
this.head = null
this.tail = null
}
}
// 以数组的方式输出节点
toArray(){
const elements = []
let curNode = this.head;
while(curNode){
elements.push(curNode)
curNode = curNode.next
}
return elements
}
}