双向链表的特征
*与单向链表的区别
1.查找方向不固定,可正向可反向查找
2.可以自我删除,不需要依靠辅助节点
*在节点内包含next和pre两个指针,一个指向下一个节点,一个指向上一个节点
*基本操作
*遍历与单向链表相同,不过其可以指向上一个节点
*添加(默认添加到链表的末尾)
1.先找到最后一个节点
2.tp。next = Person
3.Person.pre = tp
*修改和单向链表一致
*删除 1.双向链表可实现自我删除
2.直接找到待删除节点
3.tp.pre.next = tp.next //使当前节点的前一个节点next指向下一个节点
4.tp.next.pre = tp.pre //使当前节点的下一个节点pre指向前一个节点
*代码实现
package 队列的运用;
public class DoubleLinkedListDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
Person p1 = new Person(1,"迪迦","光之巨人");
Person p2 = new Person(2,"泰罗","力之巨人");
Person p3 = new Person(3,"高斯","数之巨人");
Person p4 = new Person(4,"戴拿","器之巨人");
Person p5 = new Person(4,"雷欧","法之巨人");
Person p6= new Person(6,"卡密尔","暗之女神");
//创建一个链表
SingleLinkedList1 list = new SingleLinkedList1();
//添加
list.add(p1);
list.add(p4);
list.add(p2);
list.add(p3);
list.add(p3);
//显示
list.show();
//修改
list.changeData(p5);
list.changeData(p6);
//显示
list.show();
//删除
list.deleteList(7);
list.deleteList(3);
//显示
list.show();
}
}
class DoubleLinkedList1{
//先初始化一个头节点,为恒数据,不可修改
private Person2 head = new Person2(0,"",""); //无内容
//返回头节点
public Person2 getHead() {
return head;
}
//显示当前链表
public void show(){
//判断是否为空
if(head.next == null){
System.out.println("链表为空,无法显示!");
return;
}
//head节点不能修改,因此创建临时节点,用于遍历链表
Person2 tp = head.next;
while(true){
//编写结束条件
if(tp == null){
break;
}
//输出信息
System.out.println(tp);
//每输出完,将next后移
tp = tp.next;
}
}
//添加
public void add(Person2 person){
//head节点不能修改,因此创建临时节点,用于遍历链表
Person2 tp = head;
//遍历,使其指向最后
while(true){
//当tp.next指向null时,tp指向了最后
if(tp.next == null){
break;
}
//否则,指向下一个节点
tp = tp.next;
}
//连接新节点
tp.next = person;
person.pre = tp;
}
//根据提供的节点序号,修改链表内信息
public void changeData(Person2 person){
//判断是否为空
if(head.next == null){
System.out.println("链表为空,无法修改");
return;
}
//head节点不能修改,因此创建临时节点,用于遍历链表
Person2 tp = head.next;
boolean f = false;//设置f表示寻找状态
//遍历寻找目标节点
while(true){
if(tp == null){
break; //表示遍历结束没有找到
}
if(tp.num == person.num){
f = true; //找到目标节点
break;
}
tp = tp.next;
}
//进行判断状态
if(f){
tp.name = person.name;
tp.nickname = person.nickname;
System.out.println("修改完成");
}else{
System.out.println("目标节点不存在,修改失败!");
}
}
//删除节点
public void deleteList(int no){
//head节点不能修改,因此创建临时节点,用于遍历链表
//需要定位至目标的前一个节点以供删除
Person2 tp = head.next;
//判断链表是否为空
if(head.next == null){
System.out.println("链表为空,无法删除");
return;
}
boolean f = false; //用于判断删除位置是否存在
//遍历使tp指向正确位置
while(true){
if(tp == null){
break;
}
if(tp.num == no){//序号重复
f = true; //作为记录
break;
}
tp = tp.next;
}
if(!f){
System.out.println("删除序号不存在,删除失败");
}
else{
tp.pre.next = tp.next;
//前提条件,如果删除的是最后一个节点,则不需要下面一行代码
//会出现空指针异常
if(tp.next != null){
tp.next.pre = tp.pre;
}
System.out.println("删除成功");
}
}
}
//定义一个person,每一个person就是一个节点
class Person2{
public int num;
public String name;
public String nickname; //称号
public Person2 next; //指向下一个节点
public Person2 pre; //指向前一个节点
//构造器
public Person2(int num1, String name1, String nickname1){
this.num = num1;
this.name = name1;
this.nickname = nickname1;
}
//重写toString方法
@Override
public String toString() {
return "Person [num=" + num + ", name=" + name + ", nickname=" + nickname + "]";
}
}
本文深入探讨了双向链表的特点,如可双向查找、自我删除、包含next和pre指针等。介绍了遍历、添加、修改和删除的基本操作,并通过代码示例展示了如何在`DoubleLinkedListDemo`中实现这些功能。适合理解链表结构的进阶学习。
588

被折叠的 条评论
为什么被折叠?



