最新要闻
- 最资讯丨失乐园电影迅雷下载 失乐园电影未删减版迅雷下载
- 债市相对更强,股市估值处相对低位-焦点速递
- 墓地无人汽车探测到“鬼影”!真相到底是什么?
- 上海双层敞篷观光巴士将永久退役:已达13年强制报废标准 后继无车
- 首创双枪充电遥遥领先!比亚迪腾势N7首批量产车下线
- 高考过后 多所知名大学校长纷纷出镜招生|全球短讯
- 新买不到一个月特斯拉充电冒烟爆炸 女车主:很失望 产生心理阴影_天天动态
- 世界观点:菲律宾多方人士反对日本强推核污染水排海:不要污染我们的海洋
- “泰坦尼克”号残骸观光潜艇氧气仅剩96小时 美加部署飞机搜寻
- “全球第一吊”挑战191米最大陆上风力发电机 仅17分钟升至40层楼高
- 每日短讯:男子长城藏时间胶囊12年多人留纸条 网友直呼奇妙交流:很浪漫
- 屏摄电影被男子怒斥 影院称屏摄会对胶片有损伤 网友质疑:侮辱智商?-速讯
- 每日热门:美系开卷国产电动车!别克中大型轿跑E4上市:18.99万起
- 今日阵雨叨扰,周三周四阳光又将登场,抓紧洗晒! 环球热消息
- 全球首例!杭州医生用5G帮5000公里外的新疆病人切除肝脏 画面网友惊叹
- 海口一特斯拉撞飞小车致一死一伤 现场视频被撞车360度旋转、有孩子被甩出-天天时快讯
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
全球新资讯:关于线性结构中的双向链表如何实现?
前言
在上一篇文章中,主要是给大家介绍了单向链表的特点及其原理,但是我们没有通过代码进行练习。今天我会继续通过一篇文章,来给大家讲解双向链表的内容,尤其是会通过代码来进行链表的操作,希望大家重点关注哦。
全文大约【3500】字,不说废话,只讲可以让你学到技术、明白原理的纯干货!本文带有丰富的案例及配图视频,让你更好地理解和运用文中的技术概念,并可以给你带来具有足够启迪的思考...
一. 双向链表简介
1. 概念
在上一篇文章中,我们在介绍链表的种类时,曾经提到过双向链表。双向链表相比较于单链表,除数据域外,还具前和后两个指向指针。双向链表中的结构术语可以解释为:
【资料图】
- data:链表每个结点中存储的数据域;
- next:链表每个结点中包含的指向下一个结点地址的指针域;
- prev:链表每个结点中包含的前一个结点地址的指针域。
2. 编码定义
根据上述对双向链表结点的定义,我们给出双向链表结点结构的Java定义实现:
class DNode{ Object data; Node prev; Node next;}
双向链表是一条真实存在的链表,由多个结点组成。在实际的编程中,通常会标记链表的两个特殊结点,分别为:头结点、尾结点。用另外一个变量size表示链表中元素的个数。
- 头结点:链表中的第一个结点
- 尾结点:链表中的最后一个元素
因此有如下链表类的定义:
public class DoubleLinkList{ private int size;//大小 private DNode head;//头结点 private DNode last;//尾结点}
在本篇文章接下来的内容中,我们将利用该DNode、DoubleLinkList
两个定义来实现双向链表的各项操作。
二. 常见操作
因为双向链表是单链表的基础上扩展出来的结构,因此双向链表的很多操作与单链表的操作都是相同的,比如:查找元素、更新元素、插入元素、删除元素。
1. 查找元素
1.1 查找头结点
因为DoubleLinkList中已经记录了头结点head,因此头结点的查找非常简单,如下:
public Object getHead(){ if(head == null){ return null; } return head.data;}
时间复杂度为O(1)。
1.2 查找尾结点
与头结点同理,查找尾结点的时间复杂度同样为O(1),编码如下:
public Object getLast(){ if(last == null){ return null; } return last.data;}
1.3 查找指定位置结点
当需要查找指定位置的结点元素时,双向链表比单链表的实现方式有所不同,原因是:单链表因为是单向的,因此只能从头结点向后单向查找;但双向链表前后均可查找,因此在进行指定位置查找时,为了提高查找效率,会首先判断要查找的位置处于链表的前半段还是后半段,若前半段则从头结点向后查找,若后半段则从尾结点向前查找,具体编程如下所示:
public Object get(int index){ //排除边界异常 if(index <0 || index>=size){ return null; }//要查找的位置位于链表前半段if(index < (size>>1)){ DNode x = head; for(int i = 0; i < index; i++){ x = x.next; } return x.data; }else {//要查找的位置位于链表后半段 DNode x = last; for(int i = size - 1; i >= index; i--){ x = x.prev; } return x.data; }}
在上述代码中,size >> 1 的写法比较少见,“>>”在计算机编程中代表移位操作。常见的移位操作有两种:
通过实际的编程验证,我们可以知道:执行右移1位操作,变量数据会缩小为原来的1/2。左移相反。同时,我们可以分析出时间复杂度为O(n)。
2. 更新元素
更新元素操作需要两步:
- 找到要更新的元素
- 执行更新操作
根据位置的不同,可以将更新操作分为三种情况:更新头结点,更新尾结点,更新指定位置结点。
2.1 更新头结点
更新头结点代码与查找头结点类似,如下:
public boolean updateHead(Object obj){ if(head == null){ return false; }head.data = obj;return true;}
更新头结点的时间复杂度为O(1)。
2.2 更新尾结点
public boolean updateLast(Object obj){ if(last == null){ return false; }last.data = obj;}
更新尾结点的时间复杂度同样是O(1)。
2.3 更新指定位置结点
public boolean update(int index, Object obj){ if(index < 0 || index >= size){ return false; } if(index < (size>>1)){ DNode x = head; for(int i = 0; i < index; i++){ x = x.next; } x.data = obj; }else { DNode x = last; for(int i = size-1; i >= index; i--){ x = last.prev; } x.data = obj; } return true;}public boolean addHead(Object data){ DNode h = head;DNode newNode = new DNode(null,data,h);head = newNode;if(h == null);{ last = newNode; }else { h.prev = newNode; }size++;return true;}
如上代码所示,修改指定结点元素的值采用的算法也是:先判断要操作的位置在前半段还是后半段,然后再进行精准查找,最后执行修改操作。
指定位置修改操作的时间复杂度为O(n)。
3. 插入元素
分析过了查找元素和更新元素操作的具体情况,我们很清晰的便能分析出插入元素操作的具体情况,其实也分为三种具体情景:头结点位置插入,尾结点位置插入,指定位置插入元素。
3.1 头结点位置插入
public boolean addHead(Object data){ DNode h = head;DNode newNode = new DNode(null,data,h);head = newNode;if(h == null);{ last = newNode; }else { h.prev = newNode; }size++;return true;}
根据如上代码,我们可以看到,在头结点位置插入新的元素,只需要将新添加的结点置为head结点,同时处理好新结点和原链表中头结点的指向关系即可。很明显,头结点位置插入的时间复杂度为O(1)。
3.2 尾结点位置插入
尾结点插入与头结点插入原理相同,只需要替换为尾结点以及指针的指向。如下所示:
public boolean addLast(Object data){ DNode l = last;DNode newNode = new DNode(l,data,null);last = newNode;if(last == null){ head = last; }else { l.next = newNode; }size++;return true;}
时间复杂度为O(1)。
3.3 指定位置插入
在进行指定位置插入时,编程代码稍多些,原因是需要以下几步完成:
- 判断插入的位置是否超范围
- 若插入的位置在最后,则执行在尾结点的插入逻辑
- 先根据要插入的位置,查找并获取到对应位置的结点元素
- 然后执行插入逻辑
public boolean add(int index,Object data){ if(index < 0 || index > size){ return false; } if(index == size){ addLast(data); return true; }else { //先找到要插入的指定位置的结点 DNode x = index(index); //执行插入操作 DNode prevNode = x.prev; DNode newNode = new DNode(prevNode,data,x); x.prev = newNode; if(prevNode == null){ head = newNode; }else { prevNode.next = newNode; } size++; }}//查找index位置上的结点并返回public DNode index(int index){ if( index < 0 || index >= size){ return null; }if( index < (size>>1)){ DNode x = head; for(int i = 0; i < index; i++){ x = x.next; } return x; }else { DNode x = last; for(int i = size-1; i >= index; i--){ x = x.prev; } return x; }}
根据上述代码,我们可以发现插入指定位置的代码,需要用到查找指定位置的操作,先查找再插入,因此时间复杂度同样为O(n)。
4. 删除元素
有了前面的分析经验,我们可以非常自然的分析出删除操作同样分三种:删除头结点、删除尾结点、删除指定结点。接下来,一起来看看详细的情况:
4.1 删除头结点
public Object removeHead(){ if(head == null){ return null; } DNode h = head; Object data = h.data; DNode next = h.next;//将原来头结点的数据域和指针域均赋值为null置空 h.data = null; h.next = null; //将当前结点的next作为新的头结点 head = next; //如果next为null,则说明当前链表只有一个节点,删除该节点,则链表的first、last都为null if(next == null){ last = null; }else { // next要作为新的头节点,则其prev属性为null next.prev = null; } size--; return data;}
删除头结点只涉及头结点的逻辑判断和操作,因此删除头结点时间复杂度为O(1)。
4.2 删除尾结点
与删除头结点原理相同,操作尾结点。代码如下:
public Object removeLast(){ DNode l = last; if(l == null){ return null; } Object data = l.data; DNode prev = l.prev;//将当前尾节点的属性赋值为null,为了GC清理 l.data = null; l.prev = null;// 让当前尾节点的prev作为新的尾节点,赋值给last属性 last = prev;// 如果prev为null,则说明当前链表只有一个节点,删除该节点,则链表的first、last都为null if(prev == null){ head = null; }else { // prev要作为新的尾节点,则其next属性为null prev.next = null; } size--; return data;}
很明显,删除尾结点的时间复杂度为O(1)。
4.3 删除指定结点
删除指定结点的编码实现如下:
public Object remove(int index){ if(index < 0 || index >= size){ return null; }//首先通过查找方法,查找到DNode node = index(index;//执行删除操作Object data = node.data;DNode next = node.next;DNode prev = node.prev;// 如果prev是null,则说明删除的是当前头节点,则将next作为新的头节点,赋值给headif(prev == null){ head = prev; }else { // 如果删除的不是当前头节点,则将要删除节点的prev与next连接一起,即将prev的next属性赋值成next prev.next = next; // 如果prev不是null,则赋值为null node.prev = null; }// 如果next是null,则说明删除的是当前尾节点,则将prev作为新的尾节点,赋值给lastif(next == null){ last = prev; }else { // 如果删除的不是当前尾节点,则将要删除节点的prev与next连接一起,即将next的prev赋值成prev next.prev = prev; // 如果next不是null,则赋值为null node.next = null; }//将要删除的结点的data数据域设置为nullnode.data = null;//链表的结点个数-1操作size--;return data;}
如上代码所示,删除指定位置的结点元素也需要先执行index(index)
查找算法,至于index的实现,在前文介绍指定位置插入结点操作时,已经进行了实现,此处直接进行使用。
我们不难分析得到,删除指定位置的结点的时间复杂度是O(n)。
三. 其他操作
作为一种常见的数据结构,除了对自身结点元素的一些操作,还有一些对链表状态的获取,比如链表的长度,链表是否为空等,这里给大家介绍一下双向链表的一些其他操作。
1. 链表的大小(元素结点的个数)
public int size(){ return size;}
2. 判断链表是否为空
public boolean isEmpty(){ return size == 0;}
3. 获取链表元素组成的数组
public Object[] toArray(){ Object[] result = new Object[size]; int i = 0; for(DNode node = head; node != null; node = node.next){ resunt[i++] = node.data; } return result;}
4. 清空链表
public void clear(){ for(DNode node = head; node != null; ){ DNode next = node.next; node.data = null; node.next = null; node.prev = null; node = next; } head = last = null; size = 0;}
四. 结语
至此,我们已经连续用两篇文章给大家介绍了链表的相关知识。
在上一篇文章中,我们主要介绍了链表的基础知识和单链表的常规操作,同时辅以图示来说明各种操作情况。在本篇文章中,主要是从Java编程角度作为切入点,来进一步讲解双向链表的一些操作。特别是本篇文章中的大量代码实践,需要大家能够理清逻辑关系,希望你可以动手练起来哦。
关键词:
全球新资讯:关于线性结构中的双向链表如何实现?
NCalc 学习笔记 (六)|天天观热点
也说一说IDEA热部署Web项目最终解决方案,确实大大提高工作效率
每日视点!详解在 Linux 启动时,如何自动执行命令或脚本
最资讯丨失乐园电影迅雷下载 失乐园电影未删减版迅雷下载
债市相对更强,股市估值处相对低位-焦点速递
墓地无人汽车探测到“鬼影”!真相到底是什么?
上海双层敞篷观光巴士将永久退役:已达13年强制报废标准 后继无车
首创双枪充电遥遥领先!比亚迪腾势N7首批量产车下线
高考过后 多所知名大学校长纷纷出镜招生|全球短讯
新买不到一个月特斯拉充电冒烟爆炸 女车主:很失望 产生心理阴影_天天动态
世界观点:菲律宾多方人士反对日本强推核污染水排海:不要污染我们的海洋
springboot~http请求头中如何放中文 当前快报
“泰坦尼克”号残骸观光潜艇氧气仅剩96小时 美加部署飞机搜寻
“全球第一吊”挑战191米最大陆上风力发电机 仅17分钟升至40层楼高
每日短讯:男子长城藏时间胶囊12年多人留纸条 网友直呼奇妙交流:很浪漫
屏摄电影被男子怒斥 影院称屏摄会对胶片有损伤 网友质疑:侮辱智商?-速讯
每日热门:美系开卷国产电动车!别克中大型轿跑E4上市:18.99万起
今日阵雨叨扰,周三周四阳光又将登场,抓紧洗晒! 环球热消息
【读财报】券商资管基金透视:财通、国泰君安资管年内收益领跑 中银证券业绩垫底 视讯
水电大省遭遇“水荒” 四川云南5月水电仍在下降
全球首例!杭州医生用5G帮5000公里外的新疆病人切除肝脏 画面网友惊叹
海口一特斯拉撞飞小车致一死一伤 现场视频被撞车360度旋转、有孩子被甩出-天天时快讯
电瓶车室内充电爆炸 墙都裂了 轮椅老人被吓得拔腿就跑 全球时讯
自救失败!“海航系”公司退市…
读发布!设计与部署稳定的分布式系统(第2版)笔记06_用户_世界观焦点
信息:手机可拆卸电池即将回归:利大于弊 别再被苹果牵着走
环球热资讯!回忆杀!高圆圆晒与贾静雯私照 梦回《倚天屠龙记》周芷若和赵敏
今日看点:早泄能治好吗?
100个物联网项目(基于ESP32)2快速入门
【linux命令】“瑞士军刀”nc的用法简介-天天关注
STL
马云指出淘宝天猫未来三个方向:回归淘宝、回归用户、回归互联网
花了1330万 还有600万只:巴黎向老鼠投降了 要“同居”_全球热点
冷清的618 焦虑的手机厂商:未来只能靠苹果创新了?
跳桥救人小哥引来女网友公开示爱:网友警告切勿炒作 世界热点评
中国男足亚运队1-0胜韩国U24队:孙沁涵抽射建功
美国能单挑全世界吗(美国军力全球第一敢于与世界敌么)
观焦点:登陆百度网盘错误 1550017 百度云同步盘登录失败155010
趋之若鹜的鹜什么意思_趋之若鹜
《王者荣耀》发布S32赛季漂泊之剑预告PV 两款战令皮肤奖励公布
韩国首尔教育厅将对学校供餐用水产品进行全面辐射检测 旨在保证食品安全
微信上线“安静模式” 专为有听力障碍的人创造更好的环境
《庆余年2》公布喜相逢版角色海报 增加一些重要新人物
JUC同步锁原理源码解析五----Phaser 今日热搜
ASP.NET Core MVC 从入门到精通之日志管理_世界热闻
计算几何之两条线段的交点|世界时快讯
看点:博客项目01
“狗狗嫌天热自己坐电梯回家”登上热搜 主人急里忙慌寻找
炒菜用什么油好?
车企卖衣服 不务正业? 焦点信息
微软Win11处理器要求变动:AMD、英特尔一大波新U加入支持
InnoDB 缓冲池
天天资讯:俄罗斯天然气工业银行拟参与无担保人民币债券市场
做小吃前途如何?惠记粉汤羊血加盟开店,开哪儿都火!
天天短讯!特斯拉车祸后复出 演员林志颖首次现身内地商演
专家称年轻人撑不起车市:中老年人才有足够能力拉动市场|视讯
今日精选:予以的拼音(予以)
【财经分析】数据赋能城市升级——2023中国资源型老工业城市转型发展指数研讨会在北京举办
每天喝咖啡的人 20年后都怎么样了?三大好处、三大不要 焦点精选
2024年见 龙芯也要做显卡了:IP设计已完成 还在优化
冷知识!大熊猫近视高达800度:只能看清几米之内物体 看热讯
索尼粉丝迷惑行为:请愿Xbox第一方游戏《星空》成PS5独占
开票!2023年安阳首场演唱会等你来抢!附购票入口
Liunx nginx服务|环球要闻
Manacher算法学习笔记
世界最新:799元价格屠夫!小米电视把国外品牌全打趴了
外来生物美国珍珠鳖被放生太湖:围观者欢呼雀跃|世界简讯
天天热讯:Mate发布Voicebox AI模型:仅需2秒片段即可“学会”语音细节
全球热资讯!首发4899元 外星人新款27英寸游戏显示器上架:180Hz高刷
国产操作系统赶超Win 10 统信UOS更新:换机可批量重装软件
世界头条:因编造、传播与期货交易有关的虚假信息行为 上海点钢电子商务被罚30万元
【环球热闻】Rust语言 - 接口设计的建议之显而易见(Obvious)
天猫品牌评估一般几天_天猫品牌评估_最新消息
北京电动自行车新规今起实施:电池温度达80度需有报警音
世界新消息丨女孩毕业典礼捐10万:含4年奖学金 用于帮助乡村孩子
当前观点:高通、联发科找到共同点了:骁龙8G3、天玑9300 AI性能爆发
云南普者黑现罕见的粉白相间荷花:花瓣如脂如玉 世界快播报
ppt讲课技巧互动_ppt讲课技巧 世界视点
【解决方法】锐捷 EVE 模拟器关联 Wireshark 进行抓包 焦点速讯
js-audio-recorder 插件实现web端录音
曼努埃尔·加西亚(关于曼努埃尔·加西亚介绍)
新加坡一廉价航班飞机降落后发现少个轮胎:曾出现胎压异常
全球领先!刘经南院士:北斗是唯一集通导遥等功能卫星导航系统 新视野
民营卫星俯拍四川盆地:中国两项唯一的天府之国 全球焦点
世界关注:达标没?调查称53.7%年轻人存款不足10万 感受下中等收入群体收入标准
海口一特斯拉高速行驶撞飞小车 官方通报:致一死一伤_当前独家
英雄联盟更新不动了怎么办_英雄联盟更新不动
【解决办法】DHCP Relay环境中PC无法获取IP地址,排错与解法 全球新要闻
华为云邓明昆:云原生时代,以开源赋能数字化转型
每日视讯:Quartz.net的最佳实践
动态:【高端访谈】推进金融租赁业务“全绿”转型——专访兴业金租董事长李小东
柯力传感涨停_焦点短讯
一加Ace 2 Pro把骁龙8 Gen2下放!同档位性能无敌-全球观天下
国服关了5个月 魔兽世界音乐会重返国内:门票最高680元 世界要闻
《王者荣耀》S32赛季官宣:又一个双剑战士上线 美人鱼也要来了-每日看点
明年开播!《英雄联盟》电竞剧概念海报发布:张艺谋导演、易烊千玺主演
美国波士顿机场波音737撞上空客321:今年已发生多起类似事件_世界独家
【环球报资讯】画江湖之灵主哪里可以看完整版 画江湖之灵主哪里可以看
世界新资讯:vi命令使用详解