文章目录
双向链表的知识介绍
双向链表和单向链表类似,都可以实现数据的增删改查,不同点是双向链表中多了一个pre指向前一个节点。
除了头节点head之外(没有前一个节点)每一个node都至少有三个属性
- 节点值no
- 指向下一个节点next
- 指向前一个节点pre
class DNode{
public int no;
public String name;
public DNode next;
public DNode pre;
public DNode(int no,String name){
this.no=no;
this.name=name;
}
@Override
public String toString() {
return "DNode{" +
"no=" + no +
", name='" + name + '\'' +
'}';
}
}
双向链表增删改查的思路和实现
增加节点(直接加在链表的最后面)
public void add(DNode node) {
DNode temp = head;
//先遍历到最后一个节点上
while (true) {
if (temp.next == null) {
break;
}
temp = temp.next;
}
temp.next = node;
node.pre = temp;
}
增加节点(按照顺序加入)
情况比较多,因为要判断是加载最后一个节点还是加在两个节点之间,因为多了一个前向节点信息,不做判断会出现空指针异常。
情况1,加在两个节点之间
因为加在节点之间,故当确定要加入的节点位置之后:
- node.next=temp.next
- temp.next.pre=node
- temp.next=node
- node.pre=temp
情况2,直接加在节点的最后
代码如下
//双向链表的按照顺序增
public void addByOrder(DNode node) {
DNode temp = head;
//说明链表是空的。可以直接加入
/*boolean flag=false;*/
while (true) {
//如果当前节点的后一个节点为空,或者如果当前节点的next值大于插入的值,说明应该插在temp的后面
if (temp.next == null || temp.next.no > node.no) {
break;
}
//这就不是加的事了,是改!!!
if (temp.next.no == node.no) {
System.out.println("准备插入的节点链表中已存在!");
return;
}
temp = temp.next;
}
if (temp.next != null) {
node.next = temp.next;
temp.next.pre = node;
temp.next = node;
node.pre = temp;
}
temp.next = node;
node.pre = temp;
}
删除节点
原理介绍
单向链表的删除图解:
双向链表的删除图解:
注意双向链表删除和单向链表删除的区别主要在于temp的指针指向!!!
先对比确认要删除节点的位置,有可能会没有此节点,确定有节点之后,然后开始删除操作。
双向链表的删除步骤:
- temp.next.pre=temp.pre;
- temp.pre.next=temp.next;
代码实现
//删
public void delete(int no) {
if (no <= 0) {
System.out.println("你输入的有误,要输入大于0的数");
return;
}
DNode temp = head.next;
if (temp == null) {
System.out.println("此链表为空!");
return;
}
boolean flag = false;
while (true) {
//说明没有此节点
if (temp == null) {
System.out.println("没有此节点!");
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.println("节点编号为【" + no + "】的节点已删除");
}
}
修改节点
和单向链表修改类似!
代码实现:
//改
public void update(DNode node) {
boolean flag = false;
DNode temp = head.next;
if (temp == null) {
System.out.println("此链表为空");
return;
}
while (true) {
if (temp == null) {
System.out.println("此链表中没有此节点");
break;
}
if (node.no == temp.no) {
flag = true;
break;
}
temp = temp.next;
}
if (flag) {
temp.name = node.name;
}
}
查找节点
类似于单向链表的查找思路
代码实现
public void displayAll() {
DNode temp = head.next;
if (temp == null) {
System.out.println("此双向链表为空");
}
while (temp != null) {
System.out.println(temp);
temp = temp.next;
}
}
总结单向链表与双向链表:
增 | 删 | 改 | 查 | |
---|---|---|---|---|
单向链表 | 分为有序增和无序增 | temp节点指向删除节点的前一个节点,删除时只要连接到下一节点即可 | 先确定节点中有这个节点,然后遍历确定修改节点的位置,直接修改即可。 | 先判断是否是空链表,然后进行遍历输出 |
双向链表 | 要判断是添加链表的最后还是要加在节点之间 | temp节点指向要删除的节点,删除时不仅要连接下一个节点,还要接上上一个节点 | 类似单向链表 | 类似单向链表 |