这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战
不是按传统教科书,或视频讲数据结构,而是贴合我们实际前端开发讲的,也是我工作当中总结的,仅做参考,很多地方可能与书上不一样。反正仅做参考
1. 前端js构建链表结构
1.1 单向链表结构
这里我按书上标准的,复制粘贴:线性表的链式存储,指通过任意的存储单元来存储线性表中的数据元素。 为了建立数据元素的线性关系,每一个链表的结点除了存放元素的自身信息之外,还需要存放一个指向其后继的指针。
是不是比较生涩难懂,告诉你,前端最简单的表示方法就是这样的:
const a = {
data:'A'
next:{
data:'B',
next:{
data:'C',
next:{
data:'D',
next:null
}
}
}
}
完全遵循a.next.next.next.next,只是少了一些方法,正好这些方法就可以锻炼我们的算法思维能力。从上面,我们可以清楚的明白链表结构只能从表头(上面例子就是a)存取元素
1.2 给一个对象扩展成一个链表结构
const linksListHead = {data:'A',next:null}
const linkNodeArray = [{data:'B',next:null},{data:'C',next:null},{data:'D',next:null}]
如何将linksListHead使用linkNodeArray的数据变成一个链表?
头插法
const linksListHead = {data:'A',next:null}
const linkNodeArray = [{data:'B',next:null},{data:'C',next:null},{data:'D',next:null}]
function generateLinkedList(linkhd,dataArray){
let L = linkhd
dataArray.forEach( item =>{
L.next = item;
L = item
})
return linkhd
}
const linkedListA = generateLinkedList(linksListHead,linkNodeArray)
console.log( linkedListA )
尾插法 也就是給一个链表结构的尾部节点进行插入操作,还是以上面的数据为基础,尾插法代码如下:
const linksListFoot = {data:'D',next:null}
const linkNodeArray = [{data:'C',next:null},{data:'B',next:null},{data:'A',next:null}]
function generateLinkedList(linkft,dataArray){
let L = linkft
dataArray.forEach( item =>{
item.next = L
L = item
})
return L
}
const linkedListA = generateLinkedList(linksListFoot,linkNodeArray)
console.log( linkedListA )
1.3 删除节点操作
按索引号删除 这里的链表数据就用前面生成的链表数据为基础,我们来进行链表的删除操作。
删除链表节点,重要的就是要找到被删除节点的前驱(前驱.next -> 后继)。为此我们有如下代码:
function deletLinkNodeByIndex(linkedList,index){
let i = 0;
let linkNode = linkedList;
if(index-1 < -1){
console.error(不能删除头结点元素)
}
while(i<index-1){
linkNode = linkNode.next;
i++
}
// 前驱节点
const preNode = linkNode;
// 要被删除的节点,也就是前驱的后继节点
let deletNode = preNode.next;
// 被删除的节点的后继节点替代他
const deletNodeNext = deletNode.next;
preNode.next = deletNodeNext;
deletNode = null // 释放节点删除
}
deletLinkNodeByIndex(linkedListA,2)
console.log(linkedListA)
按值删除 思路其实和上面差不多,就是按值删除要遍历整个链表,找到要删除的值的节点,然后去找他的前驱,接着找他的后继
1.4 求表长
基本思路就是,从头节点开始使用next循环,当.next的值为null的时候,遍历结束,看一共循环了多少次即可。
2.1 其他扩展
- 循环链表,根据上面我说的,其实在前端js领域,你头的next指向尾节点对象就好了
- 双向链表,加一个pre,回指就行
小测验
有一个带头的双向循环链表L,节点的结构为{prev,data,next},其中prev和next分别是指向其直接前驱和直接后继节点的指针。现在要删除指针p所指的节点,请问如何删除?