
JS数据结构--双向链表--常见操作
发布日期:2021-05-07 09:21:39
浏览次数:10
分类:原创文章
本文共 4488 字,大约阅读时间需要 14 分钟。
一.单向链表的缺点
在单向链表中,可以轻松的从头遍历到尾部,到达下一个节点,但是想回到前一个节点是很难的。
二.双向链表
- 既可以从头遍历到尾,又可以从尾遍历到头
- 链表相连的过程是双向的
- 一个节点既有向前连接的引用,也有一个向后连接的引用
- 双向链表可以解决单向链表的缺点
三.双向链表的缺点
- 每次在插入或删除某个节点时,需要处理四个引用,而不是两个,实现起来相对困难
- 与单向链表相比,占用内存空间更大
四.双向链表的特点
- 使用一个head和一个tail分别指向头部和尾部节点
- 每个节点都由三部分组成:前一个节点的指针(prev),保存的元素(item),后一个节点的指针(next)
- 双向链表的第一个节点的prev为null
- 双向链表的最后的节点的next为null
五.封装双向链表
function DoublyLinkedList(){ // 内部类:节点类 function Node(data){ this.data = data this.prev = null this.next = null } // 属性 this.head = null this.tail = null this.height = 0}
六.双向链表的基本操作
- append方法:在链表的尾部插入节点
DoublyLinkedList.prototype.append = function(data){ var newNode = new Node(data) if(this.length == 0){ this.head = newNode }else{ var current = this.head while(current.next){ current = current.next } current.next = newNode } this.length += 1}
- 链表转换成字符串:forwardString方法和backwardString方法
//forwardString方法DoublyLinkedList.prototype.forwardString = function(){ var current = this.head var resultString = '' // 依次向前遍历,获取每一个节点 while(current){ resultString += current.data + '' current = current.prev } return resultString}//backwardString方法DoublyLinkedList.prototype.backwardString = function(){ var current = this.head var resultString = '' // 依次向后遍历,获取每一个节点 while(current){ resultString += current.data + '' current = current.next } return resultString}
- insert方法:给定位置插入节点
DoublyLinkedList.prototype.insert = function(position,data){ // 越界判断 if(position < 0 || position > this.length) return false // 根据data创建新节点 var newNode = new Node(data) // 判断原来的链表是否为空 if(this.length == 0){ this.head = newNode this.tail = newNode }else{ // 1.判断position是否为0 if(position == 0){ this.head.prev = newNode newNode.next = this.head this.head = newNode }else if(position == this.length){ // 节点插入在链表尾部 this.tail.next = newNode newNode.prev = this.tail this.tail = newNode }else{ // 节点插入在中间位置 var current = this.head var index = 0 while(index++ < position){ current = current.next } newNode.next = current newNode.prev = current.prev current.prev.next = newNode current.prev = newNode } this.length += 1 return true }}
- get方法:获取给定位置的数据
// 方法1(普通方法)DoublyLinkedList.prototype.get = function(position){ // 越界判断 if(position < 0 || position >= this.length) return false // 获取元素 var current = this.head var index = 0 while(index++ < position){ current = current.next } return current.data}// 方法2DoublyLinkedList.prototype.get = function(position){ // 越界判断 // this.length / 2 > position: 从头向后遍历 // this.length / 2 < position: 从后向前遍历 // 从后向前遍历的操作: var current = this.tail var index = this.length - 1 // 链表的长度-1 while(index-- > position){ current = current.prev } return current.data}
- indexOf方法:返回元素在链表中的索引,若链表中没有该元素则返回-1
DoublyLinkedList.prototype.indexOf = function(data){ // 定义变量 var current = this.head var index = 0 // 查找和data相同的节点 while(current){ if(current.data == data){ return index }else{ current = current.next index++ } } return -1}
- update方法:修改数据元素
DoublyLinkedList.prototype.update = function(position,newData){ // 越界判断 if(position < 0 || position >= this.length) return false // 修改元素 var current = this.head var index = 0 while(index++ < position){ current = current.next } current.data = newData return true}
- removeAt方法:删除链表中的节点
DoublyLinkedList.prototype.removeAt = function(position){ //越界判断 if(position < 0 || position >= this.length) return null //判断是否只有一个节点 var current = this.head if(this.length == 1){ this.head = null this.tail = null }else{ // 判断是否删除的是第一个节点 if(position == 0){ this.head.next.prev = null this.head = this.head.next } }else if(position == this.length - 1){ // 删除最后一个节点 current = this.tail this.tail.prev.next = null this.tail = this.tail.prev }else{ var index = 0 while(index++ < position){ current = current.next } current.prev.next = current.next current.next.prev = current.prev } length -= 1 return current.data}
- remove方法:给定具体数据,删除链表中对应的节点
DoublyLinkedList.prototype.remove = function(data){ // 根据data获取下标值 var index = this.indexOf(data) // 根据index删除对应位置的节点 return this.removeAt(index)}
- isEmpty方法:判断链表是否为空
DoublyLinkedList.prototype.isEmpty = function(){ return this.length == 0}
- size方法
DoublyLinkedList.prototype.size = function(){ return this.length}
- getHead方法:获取链表的第一个元素
DoublyLinkedList.prototype.getHead = function(){ return this.head.data}
- getTail方法:获取链表的最后一个元素
DoublyLinkedList.prototype.getTail = function(){ return this.tail.data}
发表评论
最新留言
路过,博主的博客真漂亮。。
[***.116.15.85]2025年04月04日 06时39分45秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
全球首个!阿里云开源批流一体机器学习平台Alink……
2019-03-04
必须要看的网上冲浪安全攻略!
2019-03-04
红点中国、红杉中国联合领投,WakeData惟客数据完成1000万美元B轮融资
2019-03-04
看完这篇操作系统,和面试官扯皮就没问题了!
2019-03-04
OpenStack发布Ussuri版本 实现智能开源基础设施的自动化
2019-03-04
整理了一份 Docker系统知识,从安装到熟练操作看这篇就够了 | 原力计划
2019-03-04
2020 AI 产业图谱启动,勾勒中国 AI 技术与行业生态
2019-03-04
“编程能力差,90%输在了数学上!”CTO:多数程序员都是瞎努力!
2019-03-04
霍因科技获首届全国信创产业生态创新奖
2019-03-04
我是程序员,我用这种方式铭记历史
2019-03-04
F5打造“感知可控,随需而变的应用” 助力企业实现非凡数字体验
2019-03-04
CSDN湘苗培优|保持热情,告别平庸
2019-03-04
Serverless 在大规模数据处理中的实践
2019-03-04
高可用Redis服务架构分析与搭建
2019-03-04
运营商的互联网蜕变,从沃云平台开始
2019-03-04
下一次 IT 变革:边缘计算(Edge computing)
2019-03-04
Gartner的预言:通向混合IT之旅
2019-03-04
Docker精华问答 | task与executor有什么关系?
2019-03-04
英特尔强势上新一大波数据产品,小伙伴们“奔走相告”…… | 极客头条
2019-03-04
成为最大的独立开源公司,对SUSE意味着什么? | 人物志
2019-03-04