单向链表的缺点分析:
1、
单向链表,查找的方向只能是一个方向,而双向链表可以向前或者向后查找。
2、 单向链表不能自我删除,需要靠辅助节点 ,而双向链表,则可以自我删除,所以前面我们单链表删除节点时,总是找到 temp,temp 是待删除节点的前一个节点(
认真体会
)。
3、
分析了双向链表如何完成遍历,添加,修改和删除的思路。
所以双向链表跟单向链表的区别在于
多了一个pre(指向前一个节点)。
上图!
![](https://img-blog.csdnimg.cn/8f220e0724cd4698a7b582a1021c7193.png)
遍历和单链表的遍历方法相同,在此不做介绍。
添加的话有微微的不同如果是添加到最后过程应该是:
1、先找到双向链表的最后这个节点
2、temp.next = newHeroNode
3、newHeroNode.pre = temp;
上图!
如果顺序添加应该是:
1、先遍历找出新节点该插入到谁的后面
2、新节点.next = temp.next
3、temp.next.pre = 新节点
4、temp.next = 新节点
5、新节点.pre = temp
上图!
修改跟之前单链表的修改一样,只修改里面的数据。
删除,因为是双向链表,可以自我删除。
1、直接找到要删除的这个节点,比如 temp
2、temp.pre.next = temp.next
3、 temp.next.pre = temp.pre;
完整代码如下:
package datastructure.linkedlist.DoubleLinkedListDemo;
public class DoubleLinkedListDemo {
public static void main(String[] args) {
DoubleHeroNode hero1 = new DoubleHeroNode(1, "安妮", "黑暗之女");
DoubleHeroNode hero2 = new DoubleHeroNode(2, "艾希", "寒冰射手");
DoubleHeroNode hero3 = new DoubleHeroNode(3, "阿利斯塔", "牛头酋长");
DoubleHeroNode hero4 = new DoubleHeroNode(4, "崔斯特", "卡牌大师");
DoubleHeroNode hero5 = new DoubleHeroNode(5, "希维尔", "战争女神");
DoubleHeroNode hero6 = new DoubleHeroNode(5, "希维尔666", "战争女神");
//创建一个链表
DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
//加入链表
/* doubleLinkedList.add(hero1);
doubleLinkedList.add(hero2);
doubleLinkedList.add(hero3);
doubleLinkedList.add(hero4);*/
doubleLinkedList.orderadd(hero1);
doubleLinkedList.orderadd(hero5);
doubleLinkedList.orderadd(hero2);
doubleLinkedList.orderadd(hero2);
doubleLinkedList.orderadd(hero4);
doubleLinkedList.update(hero6);
// doubleLinkedList.delete(hero1);
doubleLinkedList.list();
}
}
class DoubleLinkedList {
//添加节点到双向链表
DoubleHeroNode head = new DoubleHeroNode();
public void add(DoubleHeroNode doubleHeroNode) {
DoubleHeroNode temp = head;
while (true) {
if (temp.next == null) {
//找到链表的最后
break;
}
temp = temp.next;
}
temp.next = doubleHeroNode;
doubleHeroNode.pre = temp;
}
public void orderadd(DoubleHeroNode doubleHeroNode) {
DoubleHeroNode temp = head;
while (true) {
if (temp.next == null) {
//找到链表的最后
break;
}
if (temp.next.no == doubleHeroNode.no) {//说明希望添加的 heroNode 的编号已然存在
System.out.println("准备插入的英雄的编号" + doubleHeroNode.no + "已经存在,不能继续加入");
break;
}
if (temp.next.no > doubleHeroNode.no) {//位置找到
doubleHeroNode.next = temp.next;
temp.next.pre = doubleHeroNode;
temp.next = doubleHeroNode;
doubleHeroNode.pre = temp;
break;
}
temp = temp.next;//后移,遍历当前链表
}
temp.next = doubleHeroNode;
doubleHeroNode.pre = temp;
}
public void update(DoubleHeroNode doubleHeroNode) {
DoubleHeroNode temp = head;
while (true) {
if (temp.next == null) {
//找到链表的最后
break;
}
if (temp.next.no == doubleHeroNode.no) {//找到需要修改的元素了
temp.next.name = doubleHeroNode.name;
temp.next.nickname = doubleHeroNode.nickname;
break;
}
temp = temp.next;//后移,遍历当前链表
}
}
public void delete(DoubleHeroNode doubleHeroNode) {
DoubleHeroNode temp = head;
while (true) {
if (temp.next == null) {
//找到链表的最后
break;
}
if (temp.next.no == doubleHeroNode.no) {//找到需要删除的元素了
if (temp.next.next!=null){
temp.next=temp.next.next;
temp.next.pre=temp;
break;
}else {
temp.next=null;
break;
}
}
temp = temp.next;//后移,遍历当前链表
}
}
public void list() {
DoubleHeroNode temp = head;
if (temp.next == null) {
//找到链表的最后
System.out.println("链表为空");
return;
}
while (true) {
if (temp.next == null) {
//找到链表的最后
break;
}
System.out.println(temp.next);
temp = temp.next;
}
System.out.println("================================================");
while (true) {
if (temp.pre == null) {
//找到链表的最开头
break;
}
if (temp.next == null) {
System.out.println(temp);
}
System.out.println(temp.pre);
temp = temp.pre;
}
}
}
//定义HeroNode,每一个HeroNode对象就是一个节点
class DoubleHeroNode {
public int no;//编号
public String name;//名字
public String nickname;//昵称
public DoubleHeroNode next;//指向下一个节点 如果没有则为空
public DoubleHeroNode pre;//指向上一个节点 如果没有则为空
public DoubleHeroNode() {
}
public DoubleHeroNode(int no, String name, String nickname) {
this.no = no;
this.name = name;
this.nickname = nickname;
}
@Override
public String toString() {
return "HeroNode{" +
"no=" + no +
", name='" + name + '\'' +
", nickname='" + nickname + '\'' +
'}';
}
}