双链表
双链表与单链表的区别在于双链表中除了有指向下一个节点的next,还有指向其上一个节点的pre。下面定义节点类:
//节点类,每个对象表示一个节点
class Node2 {
int no;
String name;
String nickName;
Node2 next; //指向下一个节点
Node2 pre; //指向前一个节点
Node2(int no, String name, String nickName) {
this.no = no;
this.name = name;
this.nickName = nickName;
}
@Override
public String toString() {
return "Node2{" +
"no=" + no +
", name='" + name + '\'' +
", nickName='" + nickName + '\'' +
'}';
}
}
增
将节点插入到链表尾部
-
//尾插法 public void add(Node2 newNode){ //使用临时节点指示链表最后一个节点位置 Node2 tempNode = headNode; while (true) { if (tempNode.next == null) { break; } tempNode = tempNode.next; } //最后一个节点(tempNode)的next指向待插入节点 tempNode.next = newNode; //待插入节点的pre指向tempNode newNode.pre = tempNode; }
将节点插入有序双链表使之仍然有序
-
插入的位置如果是最后一个节点的后面,要注意空指针问题。
-
使用临时变量tempNode指向插入位置的前一个节点。(也可以指向插入位置的后一个节点,代码稍微修改即可)。初始链表如下图,待插入节点P。
-
插入操作如下图:
-
//按顺序插入 public void addByOrder(Node2 newNode){ Node2 tempNode = headNode; while (tempNode.next != null){ if (tempNode.next.no == newNode.no){ System.out.println("节点已存在,不能插入"); return; } if (tempNode.next.no > newNode.no){ newNode.next = tempNode.next; tempNode.next.pre = newNode; tempNode.next = newNode; newNode.pre = tempNode; return; } tempNode = tempNode.next; } //如果插入位置在链表尾部,注意空指针异常 tempNode.next = newNode; newNode.pre = tempNode; }
删
-
双链表的删除可以直接找到要删除的节点(targetNode)。自我删除
-
①将targetNode的next节点的pre指向targetNode的pre节点;
-
②将targetNode的pre节点的next指向targetNode的next节点。
-
这里需要注意的是如果要删除的节点是最后一个节点。那么执行①的时候会报空指针异常,因为此时targetNode的next节点是null,而null.pre就会报异常。这里需要判断要删除的节点如果是最后一个节点,就不执行①语句。
-
//删除节点 public void delete(int no){ if (headNode.next == null){ System.out.println("链表是空的,不能删除~~"); return; } Node2 tempNode = headNode.next; while (tempNode != null){ if (tempNode.no == no){ //待删除节点的前一个节点的next指向待删除节点的后一个节点 tempNode.pre.next = tempNode.next; //当待删除节点是最后一个节点时,其next是null,不能将null.pre指向待删除节点的前一个节点 if (tempNode.next != null){ //待删除节点的下一个节点的pre指向待删除节点的前一个节点 tempNode.next.pre = tempNode.pre; } return; } tempNode = tempNode.next; } System.out.println("没有这个节点,不能删除哦~~"); }
改
-
双链表修改节点的代码与单链表修改方法一样。
-
//修改节点 public void update(Node2 newNode){ if (headNode.next == null){ System.out.println("链表空的,不能修改~~"); return; } Node2 tempNode = headNode.next; while (true){ if (tempNode.no == newNode.no){ tempNode.name = newNode.name; tempNode.nickName = newNode.nickName; break; } if (tempNode.next == null){ System.out.println("链表中没有你要修改的节点~~"); break; } tempNode = tempNode.next; } }
查
双链表查找节点与单链表查找方式一致
//查找节点
public void find(int no){
if (headNode.next == null){
System.out.println("链表是空的,不能查找~~~");
return;
}
Node2 tempNode = headNode.next;
while (tempNode != null){
if (tempNode.no == no){
System.out.println("no为"+no+"的节点是:"+tempNode);
return;
}
tempNode = tempNode.next;
}
System.out.println("没有查找到这个节点~~");
}
-手动整理----如有错误欢迎指出,欢迎探讨~
-转载请注明出处