数据结构 (二) ----- 单向链表双向链表
相关文章:
- 《数据结构 (一) ----- 数据结构基本概念&基于数组实现线性表》
- 《数据结构 (二) ----- 单向链表&双向链表》
文章目录
- 单链表
- 一、基本概念
- 二、接口
- 三、功能实现
- 四、几个关键的地方
- 双链表
- 一、基本概念
- 二、接口
- 三、功能实现
- 四、几个关键的地方
单链表
一、基本概念
单链表由一个个节点组成
每一个节点保存了存储的数据信息还保存了下一个节点的内存地址
public class MySingleListNode {Object data;MySingleListNode next;public MySingleListNode(Object data) {this.data = data;} }
二、接口
public interface MyList {// 新增一个元素void add(Object element);// 删除一个元素boolean delete(Object element);// 根据索引删除一个元素boolean delete(int index);// 将指定位置元素更新为新元素boolean update(int index, Object newElement);// 当前列表中是否含有target这个元素boolean contains(Object target);// 返回指定索引的元素Object get(int index);// 返回列表大小int size();// 查找指定元素下标int indexOf(Object element);
}
三、功能实现
public class MySingleLinkedList implements MyList {// 记录头节点private MySingleListNode head;// 记录尾节点private MySingleListNode last;// 链表大小private int size = 0;@Overridepublic void add(Object element) {// 如果头节点为空if (head == null) {head = new MySingleListNode(element);last = head;} else {// 否则尾节点的next指针指向新增元素节点last.next = new MySingleListNode(element);last = last.next;}size++;}@Overridepublic boolean delete(Object element) {// temp1和temp2指向的都是实际链表上每个引用指向的同一个堆内存// temp1在temp2的前一位,temp1和temp2始终是两个相邻节点MySingleListNode temp1 = null;MySingleListNode temp2 = head;while (temp2 != null) {// temp2找到链表中的elementif (temp2.data.equals(element)) {// 如果element是头节点,此时temp1指向的是nullif (temp2.equals(head)) {// 头节点后移head = head.next;} else {// 否则temp1的next指针指向temp2的下一个节点temp1.next = temp2.next;}size--;return true;}temp1 = temp2;temp2 = temp2.next;}return false;}@Overridepublic boolean delete(int index) {int i = 0;MySingleListNode temp1 = null;MySingleListNode temp2 = head;while (temp2 != null) {if (i == index) {if (i == 0) {head = head.next;} else {temp1.next = temp2.next;}size--;return true;}temp1 = temp2;temp2 = temp2.next;i++;}return false;}@Overridepublic boolean update(int index, Object newElement) {int i = 0;MySingleListNode temp = head;while (temp != null) {if (i == index) {if (i == 0) {head.data = newElement;} else {temp.data = newElement;}return true;}temp = temp.next;i++;}return false;}@Overridepublic boolean contains(Object target) {MySingleListNode temp = head;while (temp != null) {if (temp.data.equals(target)) {return true;}temp = temp.next;}return false;}@Overridepublic Object get(int index) {int i = 0;MySingleListNode temp = head;while (temp != null) {if (i == index) {return temp.data;}temp = temp.next;i++;}throw new IndexOutOfBoundsException("Index: " + index + ", " + "Size: " + size);}@Overridepublic int size() {return size;}@Overridepublic int indexOf(Object element) {int i = 0;MySingleListNode temp = head;while (temp != null) {if (temp.equals(element)) {return i;}temp = temp.next;i++;}return -1;}@Overridepublic String toString() {MySingleListNode temp = head;StringBuilder sb = new StringBuilder("[");while (temp != null) {sb.append(temp.data + (temp.next != null ? ", " : ""));// temp指向其下一个节点temp = temp.next;}sb.append("]");return sb.toString();}
}
四、几个关键的地方
void add(Object element)
功能实现public void add(Object element) {// 如果头节点为空if (head == null) {head = new MySingleListNode(element);last = head;} else {// 否则尾节点的next指针指向新增元素节点last.next = new MySingleListNode(element);last = last.next;}size++;}
boolean delete(int index)
功能实现public boolean delete(int index) {int i = 0;MySingleListNode temp1 = null;MySingleListNode temp2 = head;while (temp2 != null) {if (i == index) {if (i == 0) {head = head.next;} else {temp1.next = temp2.next;}size--;return true;}temp1 = temp2;temp2 = temp2.next;i++;}return false;}
说明:
- 建立一个变量i手动来记录temp2在链表中的位置
- temp1始终在temp2的前面一位
- 删除单链表中某个节点的思路:用前面一个节点的next引用指向被删除节点的下一个节点的内存地址,即把被删除节点的next引用赋值给前面一个节点的next引用
- 注意要单独讨论index=0 —> 被删除节点是头节点的情况
双链表
一、基本概念
head和tail两个节点为双向链表自带的哑元
其余每一个普通节点分别保存链表中的元素数据,还有其前后节点的内存地址
public class MyDoubleListNode {Object data;MyDoubleListNode pre;MyDoubleListNode next;public MyDoubleListNode(Object data) {this.data = data;} }
二、接口
public interface MyList {// 新增一个元素void add(Object element);// 删除一个元素boolean delete(Object element);// 根据索引删除一个元素boolean delete(int index);// 将指定位置元素更新为新元素boolean update(int index, Object newElement);// 当前列表中是否含有target这个元素boolean contains(Object target);// 返回指定索引的元素Object get(int index);// 返回列表大小int size();// 查找指定元素下标int indexOf(Object element);
}
三、功能实现
public class MyDoubleLinkedList implements MyList {private MyDoubleListNode head = new MyDoubleListNode(null);private MyDoubleListNode hail = new MyDoubleListNode(null);private int size = 0;public MyDoubleLinkedList() {head.next = hail;hail.pre = head;}@Overridepublic void add(Object element) {MyDoubleListNode newNode = new MyDoubleListNode(element);// 尾节点的前一个节点的next指针指向新节点hail.pre.next = newNode;// 新节点的pre指针指向尾节点的前一个节点newNode.pre = hail.pre;// 尾节点pre指针指向新节点hail.pre = newNode;// 新节点的next指针指向尾节点newNode.next = hail;size++;}@Overridepublic boolean delete(Object element) {MyDoubleListNode temp = head.next;while (temp != hail) {if(temp.data.equals(element)) {temp.pre.next = temp.next;temp.next.pre = temp.pre;size--;return true;}temp = temp.next;}return false;}@Overridepublic boolean delete(int index) {MyDoubleListNode temp = head.next;int i = 0;while (temp != hail) {if (i == index) {temp.pre.next = temp.next;temp.next.pre = temp.pre;size--;return true;}temp = temp.next;index++;}return false;}@Overridepublic boolean update(int index, Object newElement) {MyDoubleListNode temp = head.next;int i = 0;while (temp != hail) {if (index == i) {temp.data = newElement;return true;}temp = temp.next;i++;}return false;}@Overridepublic boolean contains(Object target) {return indexOf(target) != -1;}@Overridepublic Object get(int index) {int i = 0;MyDoubleListNode temp = head.next;while (temp != hail) {if (i == index) {return temp.data;}temp = temp.next;i++;}throw new IndexOutOfBoundsException("Index: " + index + ", " + "Size: " + size);}@Overridepublic int size() {return size;}@Overridepublic int indexOf(Object element) {int i = 0;MyDoubleListNode temp = head.next;while (temp != hail) {if (element.equals(temp.data)) {return i;}temp = temp.next;i++;}return -1;}@Overridepublic String toString() {StringBuilder builder = new StringBuilder("[");MyDoubleListNode temp = head.next;while (temp != hail) {builder.append(temp.data + (temp.next != hail ? ", " : ""));temp = temp.next;}builder.append("]");return builder.toString();}
}
四、几个关键的地方
temp节点扫描链表的时候,把头尾两个哑元当作头尾标志,只用扫描它们中间的节点
void add(Object newElement)
功能实现public void add(Object element) {MyDoubleListNode newNode = new MyDoubleListNode(element);// 尾节点的前一个节点的next指针指向新节点hail.pre.next = newNode;// 新节点的pre指针指向尾节点的前一个节点newNode.pre = hail.pre;// 尾节点pre指针指向新节点hail.pre = newNode;// 新节点的next指针指向尾节点newNode.next = hail;size++;}
说明:新节点左边的前后指针更新完后再去更新右边的前后指针
boolean delete(Object element)
功能实现public boolean delete(Object element) {MyDoubleListNode temp = head.next;while (temp != hail) {if(temp.data.equals(element)) {temp.pre.next = temp.next;temp.next.pre = temp.pre;size--;return true;}temp = temp.next;}return false;}
数据结构 (二) ----- 单向链表双向链表相关推荐
- Java版数据结构之单向链表 新增,有序新增的两种方式,修改和删除(CRUD)
Java版数据结构之单向链表 CRUD Java版数据结构之单向链表 新增,有序新增的两种方式,修改和删除; 留了一个疑问; 我的代码仓库:https://github.com/zhuangbinan ...
- Java版数据结构之单向链表
Java版数据结构之单向链表 我的代码仓库:https://github.com/zhuangbinan/datastructure package club.zhuangbinan.linkedli ...
- 数据结构-二叉链表存储的二叉树(利用先序遍历)
树形结构是一类重要的非线性数据结构,其中以树和二叉树最为常用.对于每一个结点至多只有两课子树的一类树,称其为二叉树.二叉树的链式存储结构是一类重要的数据结构,其形式定义如下: 而二叉树的前序.中序遍历 ...
- 数据结构——单向链表-双向链表
1.单向链表按位置修改 //按位置修改 int updata_pos(linklist *L,int pos,datatype new_e) {if(NULL==L||empty(L)||pos< ...
- Day 62 数据结构(单向链表,单向循环链表,双向链表)
1. 单向链表的设计 例程:创建一个动态单向链表 1.定义链表结点:数据域+指针域 2.定义链表结构体:头结点指针+结点数 3.初始化链表 4.指定位置插入新数据 5.删除指定位置数据 6.获取链表长 ...
- 算法与数据结构(part6)--单向链表
学习笔记,仅供参考,有错必纠 参考自:单链表头指针.头结点.头元结的辨析 文章目录 算法与数据结构–基于python 链表 为啥需要链表 什么是链表 单向链表 什么是单向链表 单列表的操作 节点的实现 ...
- 单向链表 双向链表 java代码实现
文章目录 单向链表 代码实现 单元测试 控制台打印 头插法 尾插法 双向链表 代码实现 单元测试 控制台打印 头插法 尾插法 单向链表 代码实现 package csdn.dreamzuora.lis ...
- java 单向链表 双向链表_java 单向链表与双向链表的实现
链表 单向链表 单向链表概念 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的. 这是一种物理结构,不是树那样的逻辑结构.链表和顺序表两种物理结构, ...
- 数据结构:单向链表(SingleLinkedList)删除某一节点
定义一个简单的单向链表节点 public class ListNode {int value;ListNode next;ListNode(int x) { val = x;} } 思路一 //将前一 ...
最新文章
- MVC、JSP实现mysql的增删改查功能的封装和简陋的界面交互
- BTCBCH 谁是最终的王者
- Java HashMap遍历的两种方式
- linux驱动双摄像头,详解linux 摄像头驱动编写
- RxJS CombineLatest operator 的一个具体使用例子
- linux终端lex程序运行,lex的简单使用
- spring boot集成mybatis+事务控制
- Android设计模式之——观察者模式
- 解决Some index files failed to download.They have been ignored, or old ones used instead报错
- 财智理财7破解思路与总结
- CSDN搬家到博客园
- iOS----------Apple id如何关闭双重认证?
- 图片转excel软件有哪些?这些软件你值得拥有
- aps.net mysql_支持aps版
- CodeForces - 1436D Bandit in a City
- Python数据分析第七课:时间序列数据的处理
- [CERC2014] Outer space invaders
- linux从串口接收数据丢失_Linux系统下串口接收数据,部分特殊字符丢失的解决方法...
- Markdown网页编辑器集成,stackedit二次开发,公式编辑器
- (原创)— 工作及任务分配的原则
热门文章
- iOS插件化研究之一——JavaScriptCore
- 【Java从0到架构师】日志处理 - SLF4J、Logback、Log4j 2.x
- Vue 学习笔记(3)路由的基本使用 结合 SpringBoot
- 利用反射判断初始化后的对象所有属性是否为空判断对象指定属性是否为空
- Python+BI爬取3000条车厘子数据,发现了这些秘密
- 报表session与应用session常识普及
- eclipsevue代码怎么运行_打了多年的单片机调试断点到底应该怎么设置? | 颠覆认知...
- 用python找出所有三位数中的水仙花数_python使用循环打印所有三位数水仙花数的实例...
- RxJava使用Observable.zip的Iterable参数
- python中else在循环中的使用(一分钟读懂)