数据结构与算法_01链表
数据结构与算法_01链表
- 链表
- 0、章节重点整理
- 1、单向链表
- 单向链表的尾插法
- 单向链表的结点删除
- 单向链表的结点插入
- 链表的反转
- 单向链表的串联
- 2、环形链表
- 环形链表的结点插入
- 环形链表的节点删除
- 3、双向链表
- 双向链表的节点插入
- 双向链表节点的删除
链表
参考学习书籍《图解数据结构—使用Java》
0、章节重点整理
以连接的方式表示一串数据有何好处(链表的优点)
可以共享某些空间或子表,避免空间浪费
加入或者删除节点十分容易,只需要移动指针即可
不用实现预留大的连续内存空间,可以动态链接节点试说明循环链表的优缺点
优点:
循环链表在回收到可用内存空间序列及进行多项式相加运算时,较快且有效
加入或者删除节点的运算也优于一般环形链表
缺点
循环链表必须花费额外的空间来存储链接,在读取或者寻找列表中任一节点的时间与程序都比环形链表逊色
删除节点时,必须花费额外的时间找到最后的一个节点,才可以链接新表的第一个节点。数组法和链表法表示稀疏矩阵有哪些优缺点,如果使用链表表示时,回收到AVL列表(可用内存空间列表),时间复杂度是多少?
数组法
省空间
非零项改动时要大量移动
链表法
改动时不需要大量移动
叫浪费空间
O(m+n+j)
m n 为行列数
j 为非零项试比较双向链表与单项链表的优缺点
优点
因为双向链表有两个指针分别指向节点本身前后那两个节点,所以能够很轻松的找到它的前后节点,同时从列表的任一节点也可以找到其他节点而不需要经过反转或者比较节点等处理,执行速度较快。另外如果有任一节点的链接断裂,可以轻易的由反方向遍历列表,快速完整的重建链表
缺点
由于他有两个链接,所以在加入节点或者删除节点都得花费更多的时间去移动指针,且双向的链表更加浪费空间。另外在双向链表与单向链表的算法中,双向链表在加入一个节点的时候需要改变4个指针,二删除一个节点也要改变两个指针。不过单向链表中加入节点要改变两个指针,而删除节点只需要改变一个指针。
1、单向链表
单向链表的尾插法
//尾插法,只在尾部last插入数据public void insert(int data, String name, int np){Node node = new Node(data, np, name);if(this.isEmpty()){first = node;last = node;}else {last.next= node; last = node;}}
单向链表的结点删除
- 删除列表的第一个结点只要把列表的首指针指向第二个结点即可
- 删除列表的最后一个结点只需要将最后一个结点的指针直接指向null 即可
- 删除列表内的中间结点需要将欲删除的结点的指针指向其下一个结点即可
public void delete(Node delNode){Node newNode;Node tmp;if(first.data == delNode.data){//删除头结点first = first.next;}else if (last.data == delNode.data){//删除尾结点newNode = first;while (newNode.next != last){newNode = newNode.next;}//此时newNode是last的前一个结点newNode.next = last.next; //null可以吗???last = newNode;}else{ //删除中间结点newNode = first;tmp = first;while (newNode.data != delNode.data){tmp = newNode;newNode = newNode.next;}//tmp始终都是newNode的前一个结点//此时newNode是要删除的,直接把前一个就是tmp直接指向newNode的下一个tmp = newNode.next;}}
单向链表的结点插入
- 在列表的第一个结点之前,只需要把新节点newNode 的指针移向表头first ,再把表头first 移向新节点即可
- 在列表的最后一个结点后面插入节点,把列表的最后一个结点last 的指针指向新节点,新节点指向null 即可
- 在列表的中间结点位置插入节点,如果插入的节点在X 和Y 之间,只需要将X 节点的指针指向新节点,新节点的指针指向Y 节点即可
public void insert(Node ptr){Node tmp;Node newNode;if(this.isEmpty()){first = ptr;last = ptr;}else {if(ptr.next == first){//插入到第一个结点ptr.next = first;first = ptr;}else if(ptr.next == null){//插入到最后last.next = ptr;last = ptr;}else {//插入到中间结点tmp = first;newNode = first;while(ptr.next != newNode){tmp = newNode;newNode = newNode.next;}tmp.next = ptr;ptr.next = newNode;}}}
链表的反转
//链表的反转public Node reverse(LinkedList oldList){Node current = first;Node before = null;while(current != null){last = before;before = current;current = current.next;before.next = last;}current = before;return current;}
单向链表的串联
//单向链表的串联public LinkedList concatenate(LinkedList head1, LinkedList head2){LinkedList ptr;ptr = head1;while ((ptr.last.next != null)) {ptr.last = ptr.last.next;}ptr.last.next = head2.first;return head1;}
2、环形链表
//判断链表是都为空public boolean isEmpty(){return first == null;}
环形链表的结点插入
- 直接将新节点插在第一个节点前成为表头
- 将新节点的指针指向原表头
- 找到原表的最后一个节点,并将指针指向新节点
- 将表头指向新节点
- 将新节点I 插在任意节点X 之后
- 将新节点I 的指针指向X 节点的下一个节点
- 将X 节点的指针指向I 节点
public void insert(Node trp){Node tmp;Node newNode;if(this.isEmpty()){ //插入第一个位置,空的环形链表first = trp;last = trp;last.next = first;}else if(trp.next == null){ //trp.next为空 插入是最后一个last.next = trp;last = trp;trp.next = first;}else { //中间某一个位置newNode = first;tmp = first;while (newNode.next != trp.next){if(tmp.next == first){break;}tmp = newNode;newNode = newNode.next;}tmp = newNode;trp.next = newNode;}}
环形链表的节点删除
- 删除环形链表的第一个节点
- 将表头head 移到下一个节点
- 将最后一个节点的指针移到新节点
- 删除环形链表的中间节点
- 先找到要删除的节点X 的前一个节点
- 将X 节点的前一个节点的指针指向节点X 的下一个节点
//删除某一个节点public void delete(Node delNode){Node newNode;Node tmp;if(this.isEmpty()){System.out.println("环形链表空");return;}if(first.data == delNode.data){first = first.next;if(first == null){System.out.println("环形链表空");return;}}else if(last.data == delNode.data){newNode = first;while (newNode.next != last){newNode = newNode.next;}newNode.next = last.next;last = newNode ;last.next = first;}else {newNode = first;tmp = first;while (newNode.data != delNode.data){tmp = newNode;newNode = newNode.next;}tmp.next = delNode.next;}}
3、双向链表
public class Node {int data;Node rnext;Node lnext;public Node(int data) {this.data = data;this.rnext = null;this.lnext = null;}
}
构造
左链接LLink 数据Data 右链接RLink
双向链表的节点插入
将新节点插入到列表的第一个节点前
- 将新节点的右链接RLink 指向原表的第一个节点
- 将原表的第一个节点的左链接LLink 指向新节点
- 将原表的表头head 指向新节点且新节点的左链接指向null
将新节点加入到此表的最后一个节点之后
- 将原表的最后一个节点的右链接指向新节点
- 将新节点的左链接指向原表的最后一个节点并将新节点的右链接指向null
将新节点加入到ptr 节点之后
- 将ptr 节点的右链接指向新节点
- 将新节点的左链接指向ptr 节点
- 将ptr 节点的下一个节点的左链接指向新节点
- 将新节点的右链接指向ptr 的下一个节点
//插入节点public void insert(Node newN){Node tmp;Node newNode;if(this.isEmpty()){first = newN;first.rnext = last;last = newN;last.lnext = first;}else {if(newN.lnext == null){//插入表头位置first.lnext = newN;newN.rnext = first;first = newN;}else if(newN.rnext == null){//插入表尾的位置last.rnext = newN;newN.lnext = last;last = newN;}else {//插入中间结点为位置newNode = first;tmp = first;while (newN.rnext != newNode.rnext){tmp = newNode;newNode = newNode.rnext;}tmp.rnext = newN;newN.rnext = newNode;newNode.lnext = newN;newN.lnext = tmp;}}}
双向链表节点的删除
- 删除表的第一个节点
- 将表头指针head 指到原表的第二个节点
- 将新的表头指针指向NULL
- 删除最后一个节点
- 将原表的最后一个节点之前的一个节点的右链接指向NULL即可
- 删除ptr 节点
- 将ptr 节点的前一个节点的右链接指向ptr 节点的下一个节点
- 将ptr 下一个节点的左链接指向ptr 节点的上一个节点
//删除节点public void delete(Node delNode){Node newNode;Node tmp;if(this.isEmpty()){System.out.println("表是空的,无需删除。");return;}if(delNode == null){System.out.println("删除节点输入错误。");return;}if(first.data == delNode.data){//删除节点是表头first = first.rnext;first.lnext = null;}else if(last.data == delNode.data){//删除节点是表尾newNode = first;while (newNode.rnext != last){newNode = newNode.rnext;}newNode.rnext = null;last = newNode;}else {//删除中间节点newNode = first;tmp = first;while (newNode.data != delNode.data){tmp = newNode;newNode = newNode.rnext;}tmp.rnext = delNode.rnext;tmp.lnext = delNode.lnext;}}
数据结构与算法_01链表相关推荐
- python定义链表节点_Python数据结构与算法之链表定义与用法实例详解【单链表、循环链表】...
本文实例讲述了Python数据结构与算法之链表定义与用法.分享给大家供大家参考,具体如下: 本文将为大家讲解: (1)从链表节点的定义开始,以类的方式,面向对象的思想进行链表的设计 (2)链表类插入和 ...
- 数据结构与算法之链表结构寻找p、q最近的公共祖先
链表结构,寻找p.q最近的公共祖先 数据结构与算法之链表结构寻找p.q最近的公共祖先 链表结构,寻找p.q最近的公共祖先 问题 想法 代码 问题 设一棵二叉树的结点结构为(LLINK, INFO, R ...
- 数据结构与算法--单链表相关面试题
此文章仅作为自己学习过程中的记录和总结,同时会有意地去用英文来做笔记,一些术语的英译不太准确,内容如有错漏也请多指教,谢谢! 一.概述 获取单链表的有效元素个数[新浪面试题1] 获取单链表倒数第k个结 ...
- 数据结构与算法 内核链表实现商品购物系统项目+Makefile
数据结构与算法 内核链表实现商品购物系统项目 第一章 项目实现思维 [1]编译介绍 [2]框架思维 第二章 Makefile编写 第三章 代码编写实现 [1]favorite.txt文件 [2]his ...
- 一文通数据结构与算法之——链表+常见题型与解题策略+Leetcode经典题
文章目录 1 链表 1.1 常见题型及解题策略 1.1.1 LeetCode中关于链表的题目有以下五种类型题: 1.1.2 解题策略 1.2 链表的基本内容 1.2.1 链表的基本结构: 1.2.2 ...
- JS数据结构与算法_链表
上一篇:JS数据结构与算法_栈&队列 下一篇:JS数据结构与算法_集合&字典 写在前面 说明:JS数据结构与算法 系列文章的代码和示例均可在此找到 上一篇博客发布以后,仅几天的时间竟然 ...
- java数据接口之链表_Java数据结构和算法之链表
三.链表 链结点 在链表中,每个数据项都被包含在'点"中,一个点是某个类的对象,这个类可认叫做LINK.因为一个链表中有许多类似的链结点,所以有必要用一个不同于链表的类来表达链结点.每个LI ...
- 数据结构与算法--复杂链表的复制
复杂链表的复制 题目:实现一个函数complexListNode 复制一个复杂链表.在链表中,每个节点除了有一个next指针指向下一个节点,还有另外一个before节点,before节点指向链表中任意 ...
- 数据结构与算法之-----链表(List)
[ 写在前面的话:本专栏的主要内容:数据结构与算法. 1.对于初识数据结构的小伙伴们,鉴于后面的数据结构的构建会使用到专栏前面的内容,包括具体数据结构的应用,所使用到的数据结构,也是自己 ...
- Java数据结构和算法(四)--链表
日常开发中,数组和集合使用的很多,而数组的无序插入和删除效率都是偏低的,这点在学习ArrayList源码的时候就知道了,因为需要把要 插入索引后面的所以元素全部后移一位. 而本文会详细讲解链表,可以解 ...
最新文章
- Kafka High Availability (下)
- 墙面也能变镜子,只看影子就能还原视频,MIT新算法让摄像头无死角
- SpringMVC-自定义转换器
- [iOS] dom解析xml数据,拿到lt;gt;里面的值
- navicat卡死问题
- Quartz.net定时任务的使用及获取正在运行的JOB
- java开发小程序好吗,看完必懂
- 没想到裴勇俊留了一头长发。
- Java 添加、验证PDF 数字签名
- LUA string库详解
- oracle 如何实现excel的正态分布函数normdist
- vs中资源文件和外部依赖项是什么意思?
- 火车头采集器采集教程
- 服务器限制网页只能跳转过来,限制网页只能在微信打开
- 金万维未找到服务器信息,域名解析失败原因和问题排查方法
- ClickHouce 常用字符串函数
- 用GAN的方法来进行图片匹配!休斯顿大学提出用于文本图像匹配的对抗表示学习,消除模态差异!
- python四级考试_四级英语考试如何准备呢?
- 蓝桥杯: Cowboys
- AES加密:PHP与Java互通问题