您好,欢迎来到花图问答。
搜索
您的当前位置:首页数据结构之双向链表

数据结构之双向链表

来源:花图问答

1.双向链表

1.1双向链表创建示意图

1559566817318.png

分析 双向链表的遍历,添加,修改,删除的操作思路===》代码实现:

    1. 遍历 方和 单链表一样,只是可以向前,也可以向后查找
    1. 添加 (默认添加到双向链表的最后)
    • (1) 先找到双向链表的最后这个节点
    • (2) temp.next = newHeroNode
    • (3) newHeroNode.pre = temp;
    1. 修改 思路和 原来的单向链表一样.
    1. 删除
    • (1) 因为是双向链表,因此,我们可以实现自我删除某个节点
    • (2) 直接找到要删除的这个节点,比如temp
    • (3) temp.pre.next = temp.next
    • (4) temp.next.pre = temp.pre;

1.2代码实现

package cn.smallmartial.demo;

/**
 * @Author smallmartial
 * @Date 2019/6/3
 * @Email 
 */
public class DoubleLinkedListDemo {
    public static void main(String[] args) {
        //测试
        System.out.println("双向链表测试:");
        HeroNode2 hero1 = new HeroNode2(1, "小武", "smallmartial");
        HeroNode2 hero2 = new HeroNode2(2,"宋江","及时雨");
        HeroNode2 hero3 = new HeroNode2(3,"吴用","智多星");
        HeroNode2 hero4 = new HeroNode2(4,"林冲","豹子头");
        HeroNode2 hero5 = new HeroNode2(5,"鲁智深","花和尚");

        DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
        doubleLinkedList.add(hero1);
        doubleLinkedList.add(hero2);
        doubleLinkedList.add(hero3);
        doubleLinkedList.add(hero4);
        doubleLinkedList.add(hero5);
        //显示
        doubleLinkedList.list();

        //修改
        HeroNode2 newHeroNode = new HeroNode2(1, "doudou", "smallmartial");
        doubleLinkedList.update(newHeroNode);
        System.out.println("修改后链表:");
        doubleLinkedList.list();

        //删除
        doubleLinkedList.delete(3);
        System.out.println("删除后的链表:");
        doubleLinkedList.list();

    }
}

//创建一个双向链表类
class DoubleLinkedList{
    //首先初始化一个头节点
    private HeroNode2 head= new HeroNode2(0,"","");

    //返回头节点
    public HeroNode2 getHead(){
        return head;
    }

    //遍历一个双向链表
    public void list(){
        //判断链表是否为空
        if (head.next == null){
            System.out.println("链表为空:");
            return;
        }
        //因为head节点不能动,所有需要一个辅助变量遍历
        HeroNode2 temp = head.next;
        while (true){
            if (temp == null){
                break;
            }
            //输出节点信息
            System.out.println(temp);
            //将temp后移
            temp = temp.next;
        }
    }

    public void add(HeroNode2 heroNode){
        //因为head节点不能动,所有需要一个辅助遍历temp
        HeroNode2 temp = head;
        //遍历链表,找到最后
        while (true){
            //尾节点next = null, 如果temp == null 则找到
            if (temp.next == null){
                break;
            }
            //如果没有找点将 temp 后移
            temp = temp.next;
        }
        //当退出while循环时,temp就指向了链表的最后
        //形成一个双向链表
        temp.next = heroNode;
        heroNode.pre = temp;
    }

    //修改一个节点内容
    public void update(HeroNode2 newHeroNode){
        //判断是否为空
        if (head.next == null){
            System.out.println("链表为空:");
            return;
        }

        //定义一个辅助变量
        HeroNode2 temp = head.next;
        boolean flag = false;//表示是否找到该节点
        while (true){
            if (temp == null){
                break;//遍历完
            }
            if (temp.no == newHeroNode.no){
                //找到
                flag = true;
                break;
            }
            temp = temp.next;

        }
        //根据flag判断是否要修改的节点
        if (flag){
            temp.name = newHeroNode.name;
            temp.nickName = newHeroNode.nickName;
        }else {
            System.out.println("未找到该节点"+newHeroNode.no);
        }
    }

    //从双向链表删除一个节点

    /**
     * 4) 删除
     *
     * - (1) 因为是双向链表,因此,我们可以实现自我删除某个节点
     * - (2) 直接找到要删除的这个节点,比如temp
     * - (3)  temp.pre.next = temp.next
     * - (4) temp.next.pre = temp.pre;
     * @param no
     */
    public void delete(int no){
        //判断当前链表是否为空
        if (head.next == null){
            System.out.println("链表为空:");
            return;
        }
        HeroNode2 temp = head.next;//辅助指针
        boolean flag = false;//标志是否找到
        while (true){
            if (temp == null){
                break;
            }
            if (temp.no == no){
                flag = true;//已经找到
                break;
            }
            temp = temp.next;//遍历
        }
        if (flag){
            //删除
            //temp.next = temp.next.next;
            temp.pre.next = temp.next;
            if (temp.next != null){
                temp.next.pre  = temp.pre;
            }
        }else {
            System.out.println("未找到删除的节点"+no);
        }
    }
}

//定义heroNode,每个HeroNode对象就是一个节点
class HeroNode2 {
    public int no;
    public String name;
    public String nickName;
    public HeroNode2 pre;//指向前一个节点
    public HeroNode2 next;//指向下一个节点

    public HeroNode2(int no, String name, String nickName) {
        this.no = no;
        this.name = name;
        this.nickName = nickName;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickName='" + nickName + '\'' +
                '}';
    }
}



1.3 运行结果

1559568456622.png

花图问答还为您提供以下相关内容希望对您有帮助:

肯定能懂的数据结构讲解(1)——数组与链表

双向链表:在结点中额外包含一个指向前一个结点的属性,支持双向遍历,操作更灵活。 特性:链表的删除与插入操作在时间复杂度上优于数组,尤其是双向链表。因为链表在插入或删除元素时,只需修改相关结点的指针,无需移动数据。 优点:内存使用灵活,插入和删除操作效率高。 缺点:随机访问性能较差,需从头...

双向链表是线性结构吗

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。数据结构包括数组、链表、栈、队列、树、图等。1.数组(Array)数组是一种线性数据结构,它将相同类型的元素按顺序存储在连续的内存空间中,并通过索引来访问元素。数组具有快速随机访问的特点,但插入和...

数据结构 双链表的前驱和后继到底是指什么?画个图呗~题目里面的llink...

前驱就是指逻辑上前一个结点,后继就是逻辑上后一个结点,如果用位号的观点看,前驱就是当前结点的位号-1,后继就是当前结点的位号+1。这个里面的llink指的是left link,也就是左链,自然是指向前驱结点。rlink 指的是right link,也就是右链,指向后继结点。双向链表某结点的前驱和该结点前一...

双向链表是非线性结构吗?详细点

双向链表属于线性结构,而非非线性结构。这一结构的主要特征在于,每个节点包含两个指针,分别指向其直接前驱和直接后继。从任何节点开始,都可以轻松地访问前一个或后一个节点,这使得双向链表在数据遍历和插入删除操作中表现出较高的灵活性。相较于单向链表,双向链表的优势在于其节点结构更加复杂,不仅存...

数据结构— 循环链表、双向(循环)链表

双向链表创建的过程中,每一个结点需要初始化数据域和两个指针域,一个指向直接前趋结点,另一个指向直接后继结点。创建一个双向链表line(1,2,3):比如在(1,2,3)中插入一个结点 4,变成(1,4,2,3)。实现效果图:在双向链表中插入数据时,首先完成图中标注为 1 的两步操作,然后完成...

list是什么意思

list是一个计算机专业术语,主要具有以下含义:数据结构:在编程语言中,List是类库中的一个类,可以简单视之为双向链表。它以线性列的方式管理物件集合,即在内存中按照一定的顺序存储一系列元素。元素操作:List的特色在于,在集合的任何位置增加或删除元素都很快。这是因为它通过链表的方式维护元素之间的...

什么是链表结构

链表结构是一种由一系列节点组成的数据结构,每个节点包含数据域和指针域。以下是链表结构的详细解释:1. 节点 数据域:用于存储链表中的实际数据。指针域:包含指向链表中下一个节点的指针(或引用)。2. 链表类型 单向链表:特点:每个节点只有一个指向下一个节点的指针。优点:插入和删除操作相对方便...

双向链表的优点

这种灵活的遍历方式使得双向链表在某些应用场景中具有明显的优势,如实现高效的数据结构操作和算法。此外,双向链表还具有动态调整大小的特性,能够根据实际需要动态增加或减少节点数量,而不必预先分配固定大小的空间。这种动态调整能力进一步增强了双向链表的灵活性和适应性,使其在各种编程场景中具有广泛的应用...

1,分析双向循环链表与单向链表,循环链表,双向链表间的差异;

双向链表的一般数据结构:typedef struct link{L *next, L *prev, int data}L,链表头:head 尾:tail,若tail->next = head,head->prev = tail,则为双向循环链表,否则只为双向链表 同理,单向链表:typedef struct link{L *next, int data}L; 头: head, 尾:tail,若tail->next = ...

简述三种数据结构并列举相对应的实例

双向链表:每个节点包含一个数据部分、一个指向前一个节点的指针和一个指向下一个节点的指针,如 <-1->2->3->,其中箭头表示指针方向。循环链表:最后一个节点指向第一个节点,形成一个环状结构,如 1 -> 2 -> 3 -> 1。3. 树(Tree)树是一种非线性数据结构,由节点(或称为顶点)和边...

Copyright © 2019- huatuowenda.com 版权所有 湘ICP备2023022495号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务