单链表的缺点:
- 只能从头节点开始访问整个链表
- 单链表在删除时需要借助辅助节点,不能自我删除,需要找到要删除节点的前一个节点然后进行删除操作。
双向链表:
由于单链表的缺点,延伸出了双向链表,双向链表的节点中比单链表多了一个pre,指向该节点的前驱节点,在访问链表时既可以向前访问也可以向后访问。而且双向链表中的节点可以自我删除。
//temp即是当前要删除的节点
temp.pre.next = temp.next;
temp.next.pre = temp.pre;
注意在双向链表进行删除时,要判断删除的节点是否为最后一个节点,如果不加判断条件使用上述两行代码则会报错,如果temp为最后一个节点,则temp.next为null,所以temp.next.pre会出错。当为最后一个节点时,只需要temp.pre.next = temp.next;即可。
代码实现(java)
package com.doublelinkedlist;
public class LinkedList2 {
public static void main(String[] args) {
System.out.println("双向链表测试:");
DoubleLinkedList List2 = new DoubleLinkedList();
Node2 node1 = new Node2(1, "张三", "第一");
Node2 node2 = new Node2(2, "李四", "第二");
Node2 node3 = new Node2(3, "王五", "第三");
List2.addNode2(node1);
List2.addNode2(node2);
List2.addNode2(node3);
//添加节点后遍历
List2.showLinkedList2();
//修改节点的值,传入no值和修改后的信息,与单链表相同
List2.changeNode2(2, "张张", "第0");
List2.showLinkedList2();
//删除节点,传入no值
List2.del2(3);
List2.showLinkedList2();
}
}
class Node2 {
public int no;
public String name;
public String nickName;
public Node2 next;
public Node2 pre;
public Node2(int no, String name, String nickName) {
this.no = no;
this.name = name;
this.nickName = nickName;
}
}
class DoubleLinkedList {
private Node2 head = new Node2(0, "", "");
//插入节点
public void addNode2(Node2 node) {
Node2 temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = node;
node.next = null;
node.pre = temp;
}
//修改节点的值,此处要用no做判断,no不能被修改
public void changeNode2(int no, String name, String nickName) {
Node2 temp = head;
Boolean flag = false;
if (temp.next == null) {
System.out.println("链表为空不能修改!");
}
while (temp.next != null) {
if (temp.next.no == no) {
temp.next.name = name;
temp.next.nickName = nickName;
flag = true;
break;
}
temp = temp.next;
}
if (flag == false) {
System.out.println("链表中没有该节点!");
}
}
//根据no删除对应节点
public void del2(int no) {
Node2 temp = head.next;
Boolean flag = false;
if (temp == null) {
System.out.println("链表为空,不能删除!");
return;
}
while (temp != null) {
if (temp.no == no) {
temp.pre.next = temp.next;
if (temp.next != null) {
temp.next.pre = temp.pre;
}
flag = true;
break;
}
temp = temp.next;
}
if (flag == false) {
System.out.println("链表中没有该节点!");
}
}
//遍历输出链表中节点信息
public void showLinkedList2() {
Node2 temp = head;
if (temp.next == null) {
System.out.println("链表为空!!!");
}
while (temp.next != null) {
System.out.printf("no = %d name = %s nickName = %s;\n", temp.next.no, temp.next.name, temp.next.nickName);
temp = temp.next;
}
}
}