这篇文章主要为大家详细介绍了基于Java实现双向链表,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
本文实例为大家分享了Java实现双向链表的具体代码,供大家参考,具体内容如下
双向链表与单链表的对比:
1、单向链表查找只能是一个方向,双向链表可以向前或者向后查找
2、单向链表不能自我删除,需要靠辅助节点**(即需要通过找到要删除的节点的前一个节点,通过该节点进行删除的操作,而双向链表只需找到要删除的节点就行了)**。双向链表可以自我删除
双向链表示意图
分析(代码实现原理):temp为辅助节点(因为头节点不可动)
1、遍历:方式与单链表一致,但是是双向的,可以向前,也可以向后
2、添加(默认添加到最后面)
(1)先找到链表的最后一个节点
(2)temp.next=newnode
(3)newnode.pre=temp
3、修改:思路与原理与单链表一致
4、删除:
(1)因为是双向链表,可以自我删除该节点
(2)找到要删除的节点,假设这个节点为temp
(3)temp.pre.next=temp.next
(4)temp.next.pre=temp.pre
添加节点(按顺序):
步骤:
(1)找到要添加节点位置的前一个节点(temp)
(2)node.next=temp.next
(3)temp.next.pre=node
(4)temp.next=node
(5)node.pre=temp
代码实现:
public class DoubleLinkedList {
//创建头结点。表示链表的头
private Node Head=new Node(0,"","");
//返回头结点
public Node getHead() {
return Head;
}
//AddNode1:添加节点到单链表的尾部
//思路:当不考虑节点顺序
//1、找到链表的最后一个节点
//2、将最后这个节点的Next指向新节点
public void AddNode1(Node node) {
//因为头节点不能动,所以需要一个辅助节点遍历
Node temp=Head;
while(true) {
//找到链表的最后一个节点
if(temp.next==null) {
break;
}
//否则temp=temp的下一个节点
temp=temp.next;
}
//循环出来之后,temp是最后一个节点
temp.next=node;
node.pre=temp;
}
//AddNode2:添加节点,按顺序
public void AddNode2(Node node) {
//因为头结点不能动,所以需要一个辅助节点遍历,找到添加新节点的位置
Node temp=Head;
boolean flag=false; //用于标识链表中是否已经存在新节点的顺序
while(true) {
//如果该节点是最后一个节点,则新节点添加到最后一个位置
if(temp.next==null) {
break;
}else if(temp.next.number>node.number) { //说明找到了添加新节点的位置
break;
}else if(temp.next.number==node.number) { //说明新节点的顺序已经存在在链表中
flag=true;
}
temp=temp.next;
}
if(flag) {
System.out.println("该节点的顺序已经存在,插入失败");
}else {
//则说明新节点在链表中不存在,插入新节点
//新节点的下一个节点=辅助节点的下一个节点
node.next=temp.next;
if(temp.next!=null) { //如果temp的下一个节点不为空,则temp的下一个节点的前一个节点为新节点
temp.next.pre=node;
}
//辅助节点的下一个节点=新节点
temp.next=node;
//新节点的前一个节点为辅助节点
node.pre=temp;
}
}
//删除节点
public void remove(Node node) {
if(Head.next==null) {
System.out.println("链表为空!");
return;
}
//创建辅助节点
Node temp=Head.next;
boolean flag=false; //标识是否找到了要删除的节点
while(true) {
if(temp==null) { //遍历完链表了
break;
}else if(temp.number==node.number) { //找到要删除的节点了
flag=true;
break;
}
temp=temp.next;
}
if(flag) { //链表中存在要删除的节点
temp.pre.next=temp.next; //令temp的前一个节点的下一个节点为temp的后一个节点
if(temp.next!=null) { //如果temp不为最后一个节点的话
temp.next.pre=temp.pre; //令temp的下一个节点的前一个节点为temp的前一个节点
}
}else {
System.out.printf("不存在编号为%d的节点",node.number);
}
}
//修改节点,按照节点的Number来修改
public void update(Node newNode) {
if(Head.next==null) {
System.out.println("链表为空!");
return;
}
//创建辅助节点,对链表遍历,知道找到等于修改节点的number的时候
Node temp=Head.next;
boolean flag=false; //用来标识是否找到了修改节点的Number
while(true) {
if(temp==null) { //则已经遍历完链表
break;
}
if(temp.number==newNode.number) {
flag=true;
break;
}
temp=temp.next;
}
if(flag) {
temp.name=newNode.name;
temp.nickName=newNode.nickName;
}else {
System.out.printf("没有找到编号为%d的节点",newNode.number);
}
}
//展示链表
public void show() {
if(Head.next==null) {
System.out.println("链表为空!");
return;
}
//因为头节点不能动,所以通过辅助节点遍历链表
Node temp=Head.next;
while(true) {
//判断是不是最后一个节点
if(temp.next==null) {
System.out.println(temp);
break;
}
System.out.println(temp);
//temp指向下一个节点
temp=temp.next;
}
}
}
//创建节点
class Node{
public int number;
public String name;
public String nickName;
public Node next; //指向下一个节点
public Node pre;//指向前一个节点
//构造器
public Node(int number,String name,String nickName) {
this.number=number;
this.name=name;
this.nickName=nickName;
}
@Override
public String toString() {
return "Node [number=" + number + ", name=" + name + ", nickName=" + nickName + "]";
}
}
测试代码:
public static void main(String[] args) {
// TODO 自动生成的方法存根
Node node1=new Node(1,"宋江","及时雨");
Node node2=new Node(2,"卢俊义","玉麒麟");
Node node3=new Node(3,"吴用","智多星");
Node node4=new Node(4,"林冲","豹子头");
Node node5=new Node(4,"linchong","豹子头");
//创建一个链表
DoubleLinkedList linkedList=new DoubleLinkedList();
linkedList.AddNode2(node1);
linkedList.AddNode2(node3);
linkedList.AddNode2(node4);
linkedList.AddNode2(node2);
linkedList.show();
System.out.println("------------");
linkedList.remove(node4);
linkedList.show();
}
结果:
Node [number=1, name=宋江, nickName=及时雨]
Node [number=2, name=卢俊义, nickName=玉麒麟]
Node [number=3, name=吴用, nickName=智多星]
Node [number=4, name=林冲, nickName=豹子头]
————————————————————————
Node [number=1, name=宋江, nickName=及时雨]
Node [number=2, name=卢俊义, nickName=玉麒麟]
Node [number=3, name=吴用, nickName=智多星]
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程学习网。
本文标题为:基于Java实现双向链表
基础教程推荐
- Java文件管理操作的知识点整理 2023-05-19
- Java数据结构之对象比较详解 2023-03-07
- java实现多人聊天系统 2023-05-19
- JDK数组阻塞队列源码深入分析总结 2023-04-18
- Java实现查找文件和替换文件内容 2023-04-06
- ConditionalOnProperty配置swagger不生效问题及解决 2023-01-02
- Java并发编程进阶之线程控制篇 2023-03-07
- java基础知识之FileInputStream流的使用 2023-08-11
- springboot自定义starter方法及注解实例 2023-03-31
- Java实现线程插队的示例代码 2022-09-03