单链表与双链表的区别
- 单链表的查找方向只能是一个方向,双链表的查找方向可以向前也可以向后
- 单链表不能自我删除(需要借助前一个节点来删除当前节点),双链表可以自我删除
双链表的分析
1. 遍历
双链表可以向前查找,也可以向后遍历查找
2. 添加
默认在最后一个节点 temp
后面添加:
先循环找到最后一个节点
temp.next = newHeroNode;
newHeroNode.pre = temp
3. 修改
找到要修改的节点,然后直接修改值即可(与单链表的修改相同)
4. 删除
找到要删除的节点 temp
:
temp.pre.next = temp.next;
temp.next.pre = temp.pre; (如果是最后一个节点,就不用这一步了)
双链表代码实现
作业
完整代码如下
package com.DoubleLinkedList04;
public class DoubleLinkedListDemo {
public static void main(String[] args) {
HeroNode heroNode1 = new HeroNode(1, "宋江", "及时雨");
HeroNode heroNode2 = new HeroNode(2, "晁盖", "玉麒麟");
HeroNode heroNode3 = new HeroNode(3, "吴用", "智多星");
HeroNode heroNode4 = new HeroNode(4, "林冲", "豹子头");
HeroNode heroNode5 = new HeroNode(4, "林冲~~", "豹子头");
DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
doubleLinkedList.addByOrder(heroNode4);
doubleLinkedList.addByOrder(heroNode2);
doubleLinkedList.addByOrder(heroNode3);
doubleLinkedList.addByOrder(heroNode5);
doubleLinkedList.addByOrder(heroNode1);
doubleLinkedList.list();
/*HeroNode heroNode = new HeroNode(4, "林冲~~~", "豹子头~~~");
doubleLinkedList.update(heroNode);
System.out.println("修改后的数据:");
doubleLinkedList.list();
doubleLinkedList.del(1);
doubleLinkedList.del(4);
doubleLinkedList.del(3);
doubleLinkedList.del(2);
System.out.println("删除后的数据:");
doubleLinkedList.list();*/
}
}
class HeroNode {
public int no;
public String name;
public String nickname;
public HeroNode pre;
public HeroNode next;
// 为了创建节点对象
public HeroNode(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 + '\'' +
'}';
}
}
class DoubleLinkedList {
// 先初始化一个头结点,头结点不动,不存放具体数据
private HeroNode head = new HeroNode(0, "", "");
// 返回头结点
public HeroNode getHead() {
return head;
}
// 遍历双向列表
public void list() {
if (head.next == null) {
System.out.println("该双链表为空~~~");
return;
}
HeroNode temp = head.next;
while (temp != null) {
System.out.println(temp.toString());
temp = temp.next;
}
}
// 为双向列表添加节点
public void add(HeroNode heroNode) {
HeroNode temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = heroNode;
heroNode.pre = temp;
}
// 为双向列表修改节点
public void update(HeroNode heroNode) {
if(head.next == null) {
System.out.println("该双链表为空~~~");
return;
}
HeroNode temp = head.next;
while (temp != null) {
if (temp.no == heroNode.no) {
temp.name = heroNode.name;
temp.nickname = heroNode.nickname;
return;
}
temp = temp.next;
}
System.out.printf("双链表中不存在编号为 %d 的节点~~~", heroNode.no);
}
// 双链表的删除操作
public void del(int no) {
if (head.next == null) {
System.out.println("该链表为空,没有可以删除的节点~~~");
return;
}
HeroNode temp = head.next;
while (temp != null) {
if (temp.no == no) {
temp.pre.next = temp.next;
if (temp.next != null) {
temp.next.pre = temp.pre;
}
return;
}
temp = temp.next;
}
System.out.printf("该双链表中没有编号为 %d 的员工~~~", no);
}
// 双链表按编号顺序添加
public void addByOrder(HeroNode heroNode) {
HeroNode temp = head;
while (temp.next != null) {
if (temp.next.no < heroNode.no) {
temp = temp.next;
}else if (temp.next.no > heroNode.no) {
// 建立当前节点和后面节点的联系(一定不是最后一个节点)
temp.next.pre = heroNode;
heroNode.next = temp.next;
break;
}else {
System.out.printf("编号为 %d 的节点已经存在,添加失败~~~\n", heroNode.no);
return;
}
}
//建立当前节点和前面节点的联系
temp.next = heroNode;
heroNode.pre = temp;
}
}