ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

链表(双向链表)

2021-09-26 18:32:57  阅读:127  来源: 互联网

标签:temp no next 链表 双向 Node3 节点


链表(双向链表)

需求

单向链表:查找方向只能是一个方向,即通过next域去查找下一个节点,单向链表删除时,也不能自动删除,在前面单向链表中由于我们只能通过next域向后查找,所以在很多操作时需要借助辅助变量(节点)temp去找删除节点的前一个节点进行操作。

双向链表:可以向前或向后查找,提供两个方向的查找,双向链表也可以提供自动删除

思路分析

在节点中新增一个变量指向前一个节点,使得链表成为双向链表。

class Node3 {
    public int no;
    public String name;
    public Node3 next;//指向下一个节点,默认为null
    public Node3 pre;//指向上一个节点,默认为null
    //构造器
    public Node3(int no, String name){
        this.no=no;
        this.name=name;
    }

    @Override
    public String toString() {
        return "Node3{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';//不加next域,否则会把后面的节点打出
    }
}

链表的增,删,改,查

双向链表添加
(默认添加到链表最后)
同单向链表先找到双向链表最后一个节点temp

temp.next=newnode3;
newnode3.pre=temp;

代码实现(方法段)

public void addDLL(Node3 node3) {
        Node3 temp = head;//因为head节点不能动,所以另外定义一个变量,将head节点赋给它
        //进行遍历找到链表的最后一个节点
        boolean flag = false;//flag表示节点是否存在,默认为flase(加入节点是否与原有节点相同)
        while (true) {
            if (temp.next == null)
                break;
            if (temp.next.no > node3.no)//因为链表只能后接所以与要添加变量比较序号的是temp.next而不是temp
                break;
            else if (temp.next.no == node3.no) {
                flag = true;//序号存在
                break;
            }
            temp = temp.next;
        }
        //退出while循环时,temp就指向了链表最后
        temp.next=node3;
        node3.pre=temp;
        //实现链表的双向连接
        }

    }

双向链表修改
双向链表的修改与单向链表一样,依序号找到后修改即可

双向链表删除
因为是双向链表,因此可以实现自我删除某个节点,例找到待删除节点temp

temp.next.pre=temp.pre;
temp.pre.next=temp.next;

代码实现(方法段)

public void delete(int no){
        Node3 temp=head.next;
        boolean isFind=false;
        if(temp==null){
            System.out.println("链表为空,无法删除");
        }
        while (true){
            if(temp.next==null){
                break;
            }
            if (temp.no==no){
                isFind=true;
                break;
            }
            temp=temp.next;
        }
        if(isFind){
            temp.pre.next=temp.next;
            //注意当temp是最后一个节点时,temp.next.pre将会出现空指针异常
            //所以另一段删除部分需要一定的条件
            if (temp.next!=null){
                temp.pre.next=temp.next;
            }
        }else{
            System.out.println("未找到序号所对应的节点,删除失败");
        }
    }

(代码实现)整体部分

package datastructure;
//双向链表
public class linkedIist3 {
    public static void main(String[] args) {
        //双向链表的测试
        Node3 node1=new Node3(1,"一号") ;
        Node3 node2=new Node3(2,"二号") ;
        Node3 node3=new Node3(3,"三号") ;
        Node3 node4=new Node3(4,"四号") ;
        Node3 node5=new Node3(5,"五号") ;
        //创建链表
        Doublielinklist Dlink=new Doublielinklist();

        //所添加数据按照序号排列
        Dlink.addDLL(node1);
        Dlink.addDLL(node2);
        Dlink.addDLL(node3);
        Dlink.addDLL(node4);
        Dlink.addDLL(node5);

        //测试节点
        Node3 Tnode=new Node3(2,"贰号") ;
        Dlink.update(Tnode);
        Dlink.delete(4);

        //显示列表
        Dlink.show();

    }
}
class Doublielinklist{
    private Node3 head=new Node3(0,"");
    //返回头节点
    public Node3 getHead(){
        return head;
    }
    //展示链表
    public void show() {
        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }
        //head节点不能动
        Node3 temp = head.next;
        while (true) {
            if (temp == null) {
                break;
            }
            System.out.println(temp);
            temp = temp.next;
        }
    }
    public void addDLL(Node3 node){
        Node3 temp=head;//因为head节点不能动,所以另外定义一个变量,将head节点赋给它
        //进行遍历找到链表的最后一个节点
        while(true){
            if(temp.next==null)
                break;
            temp=temp.next;
        }
        //将新节点接到原链表尾,新的节点代替了null
        temp.next=node;
        node.pre=temp;

    }
    public void update(Node3 newNode){
        Node3 temp=head.next;
        if (temp==null){
            System.out.println("链表为空");
        }
        //更新(修改)链表节点前先找到该节点
        boolean flag=false;//定义一个变量表示是否更新节点是否在链表内
        while (true){
            if (temp==null)
                break;
            if (temp.no==newNode.no){
                flag=true;
                break;
            }
            temp=temp.next;
        }
        if (flag){
            temp.name=newNode.name;
        }else{//没有找到节点
            System.out.println("未找到该节点,无法修改");
        }
    }
    public void delete(int no){
        Node3 temp=head.next;
        boolean isFind=false;
        if(temp==null){
            System.out.println("链表为空,无法删除");
        }
        while (true){
            if(temp.next==null){
                break;
            }
            if (temp.no==no){
                isFind=true;
                break;
            }
            temp=temp.next;
        }
        if(isFind){
            temp.pre.next=temp.next;
            //注意当temp是最后一个节点时,temp.next.pre将会出现空指针异常
            //所以另一段删除部分需要一定的条件
            if (temp.next!=null){
                temp.pre.next=temp.next;
            }
        }else{
            System.out.println("未找到序号所对应的节点,删除失败");
        }
    }

    }
class Node3 {
    public int no;
    public String name;
    public Node3 next;//指向下一个节点,默认为null
    public Node3 pre;//指向上一个节点,默认为null
    //构造器
    public Node3(int no, String name){
        this.no=no;
        this.name=name;
    }

    @Override
    public String toString() {
        return "Node3{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';//不加next域,否则会把后面的节点打出
    }


}

标签:temp,no,next,链表,双向,Node3,节点
来源: https://blog.csdn.net/LateNight_LL/article/details/120491672

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有