单链表只可以有一个方向进行查找,而双向链表可以向前或者向后查找
单向链表不可以自我删除,需要一个辅助节点,而双向链表可以实现自我删除
遍历:
双向链表的遍历思路和单链表的思路是一样的,只是可以向前,也可以向后
添加:(默认添加到双向链表的最后)
先找到双向链表最后的这个节点;
temp.next = 新节点;
新节点.pre = temp;
修改:
修改思路和双向链表是一样的
删除:
因为是双链表,所以可以自我删除某个节点。
找到要删除的那个节点,temp;
temp.pre.next = temp.next;
temp.next.pre = temp.pre;
这就可以实现删除节点。
package com.gsy.linkedlist;
/**
* @program: DataStructures
* @description: 双向链表
* @author: GSY
* @create: 2020-03-29 17:11
**/
public class DoubleLinkedListDemo {
public static void main(String[] args){
System.out.print("双向链表的测试\n");
HeroNodeT heroNode1 = new HeroNodeT(1,"武松","行者");
HeroNodeT heroNode2 = new HeroNodeT(2,"关羽","武圣");
HeroNodeT heroNode3 = new HeroNodeT(3,"花容","小李广");
HeroNodeT heroNode4 = new HeroNodeT(4,"林冲","豹子头");
HeroNodeT heroNode5 = new HeroNodeT(5,"卢俊义","玉麒麟");
DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
doubleLinkedList.add(heroNode3);
doubleLinkedList.add(heroNode5);
doubleLinkedList.add(heroNode2);
doubleLinkedList.add(heroNode1);
doubleLinkedList.add(heroNode4);
doubleLinkedList.printList();
System.out.print("修改链表\n");
HeroNodeT heroNode = new HeroNodeT(5,"卢爷","金麒麟");
doubleLinkedList.update(heroNode);
doubleLinkedList.printList();
//删除
doubleLinkedList.del(1);
System.out.print("删除之后\n");
doubleLinkedList.printList();
}
}
//双向链表
class DoubleLinkedList{
private HeroNodeT head = new HeroNodeT(0,"","");
//返回头节点
public HeroNodeT getHead() {
return head;
}
//遍历双向链表
public void printList(){
HeroNodeT temp = head.next;
while (true){
if (temp == null){
break;
}
System.out.println(temp);
temp = temp.next;
}
}
//添加节点到双链表
public void add(HeroNodeT heroNodeT){
//因为head节点不可以动,所以我们添加一个辅助遍历temp
HeroNodeT temp = head;
//遍历链表找到最后
while (true){
//判断是否是最后一个节点
if (temp.next == null){
break;//找到最后节点就退出
}
temp = temp.next;//不是最后一个节点就往后移
}
temp.next = heroNodeT;//推出循环以后就将temp指向链表最后,然后就将传入的节点加入到链表最后
heroNodeT.pre = temp;//将插入的节点的pre指向前一个节点
}
//修改
public void update(HeroNodeT newHeroNode){
//先判断链表是否为空
if (head.next == null){
System.out.println("链表为空");
return;
}
//找到需要修改的节点,根据编号
HeroNodeT temp = head.next;
boolean flag = false;
while (true){
if (temp == null){
break;
}
if (temp.no == newHeroNode.no){
flag = true;
break;
}
temp = temp.next;
}
if (flag){
temp.name = newHeroNode.name;
temp.nickName = newHeroNode.nickName;
}else{
System.out.printf("编号为 %d 的节点没有找到\n",newHeroNode.no);
}
}
//删除一个节点
//双向链表我们可以直接找到要删除的节点,然后直接删除
public void del(int no){
//判断链表是否为空
if (head.next == null){
System.out.printf("链表为空\n");
return;
}
HeroNodeT temp = head.next;
boolean flag = false;//标志是否找到要删除的节点
while (true){
if (temp == null){//已经到节点最后
break;
}
if (temp.no == no){
flag = true;
break;
}
temp = temp.next;
}
if (flag){
temp.pre.next = temp.next;
temp.next.pre = temp.pre;
System.out.printf("删除 %d 节点\n",no);
}else {
System.out.printf("删除失败\n");
}
}
}
//定义一个HeroNodeT,每个HeroNodeT对象就是一个节点
class HeroNodeT{
public int no;
public String name;
public String nickName;
public HeroNodeT next;//指向下一个节点
public HeroNodeT pre; //指向上一个节点
//构造器
public HeroNodeT(int no,String name,String nickName){
this.no = no;
this.name = name;
this.nickName = nickName;
}
@Override
public String toString() {
return "HeroNodeT{" +
"no=" + no +
", name='" + name + '\'' +
", nickName='" + nickName + '\'' +
'}';
}
}