双向链表的知识

双向链表的知识介绍

双向链表和单向链表类似,都可以实现数据的增删改查,不同点是双向链表中多了一个pre指向前一个节点。双向链表的示意图
除了头节点head之外(没有前一个节点)每一个node都至少有三个属性

  1. 节点值no
  2. 指向下一个节点next
  3. 指向前一个节点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,加在两个节点之间

在这里插入图片描述
因为加在节点之间,故当确定要加入的节点位置之后:

  1. node.next=temp.next
  2. temp.next.pre=node
  3. temp.next=node
  4. 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的指针指向!!!
先对比确认要删除节点的位置,有可能会没有此节点,确定有节点之后,然后开始删除操作。
双向链表的删除步骤:

  1. temp.next.pre=temp.pre;
  2. 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节点指向要删除的节点,删除时不仅要连接下一个节点,还要接上上一个节点类似单向链表类似单向链表
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值