(六)数据结构-双向链表

命运对每个人都是一样的,不一样的是各自的努力和付出不同,付出的越多,努力的越多,得到的回报也越多,在你累的时候请看一下身边比你成功却还比你更努力的人,这样,你就会更有动力。

导读:本篇文章讲解 (六)数据结构-双向链表,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

  1. 单链表缺点分析

(1)单向链表,查找的方向只能 只能是一个方向,而双向链表客户向前或者向后查找。

(2)单向链表不能自我删除,需要靠辅助节点,而双向链表,则可以自我删除。

2.什么是双向链表

双向链表也叫双链表,是链表的一种,它的每个数据节点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。

(六)数据结构-双向链表

2.1 属性

节点 Node相关属性。

存储的数据 T data、直接前驱节点 Node pri、直接后继节点 Node next

private static class Node<T> {
    private T data;
    private Node<T> pre;
    private Node<T> next;
}

2.2应用实例

使用带head头的双向链表实现-水浒英雄排行榜管理。

分析双向链表的遍历、添加、修改、删除的操作思路。

(1)遍历 和单链表一样,只是可以向前,也可以向后查找

(2)添加(添加到最后)

  1. 先找到双向链表的最后这个节点;

  1. temp.next=newHeroNode;

  1. newHeroNode.pre=temp;

(3)添加(按编号进行排序)

  1. 先找到符合条件节点的上一个节点,假设是 temp;

  1. heroNode.pre = temp;

  1. heroNode.next = temp.next;

  1. temp.next.pre = heroNode;

  1. temp.next = heroNode;

(3)修改 思路和单链表一样

(4)删除

  1. 因为是双向链表,因此,我们可以实现自我删除某个节点;

  1. 直接找到要删除的节点,假设是 temp;

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

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

代码实现:

/**
 * 双向链表
 */
public class DoubleLinkedListDemo {
    public static void main(String[] args) {
        HeroNode2 hero1 = new HeroNode2(1, "宋江", "及时雨");
        HeroNode2 hero2 = new HeroNode2(2, "卢俊义", "玉麒麟");
        HeroNode2 hero3 = new HeroNode2(3, "吴用", "智多星");
        HeroNode2 hero4 = new HeroNode2(4, "林冲", "豹子头");

        // 创建一个双向链表
        DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
        /*doubleLinkedList.add(hero1);
        doubleLinkedList.add(hero3);
        doubleLinkedList.add(hero2);
        doubleLinkedList.add(hero4);*/

        doubleLinkedList.addByOrder(hero2);
        doubleLinkedList.addByOrder(hero3);
        doubleLinkedList.addByOrder(hero1);
        doubleLinkedList.addByOrder(hero4);
        System.out.println("~~~~~~~~~新增后链表~~~~~~~~~~");
        // 显示链表
        doubleLinkedList.list();

        // 修改
        HeroNode2 updateNode = new HeroNode2(3, "小吴", "智多星~~~");
        doubleLinkedList.update(updateNode);
        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() {
        HeroNode2 temp = head.next;
        // 判断链表是否为空
        if (temp == null) {
            System.out.println("链表为空");
            return;
        }

        while (temp != null) {
            System.out.println(temp);
            temp = temp.next;
        }
    }

    // 添加节点到链表尾部
    public void add(HeroNode2 heroNode) {
        // 辅助指针
        HeroNode2 temp = head;

        while (true) {
            // 遍历到最后
            if (temp.next == null) {
                break;
            }

            // 指针后移
            temp = temp.next;
        }

        temp.next = heroNode;
        heroNode.pre = temp;
    }

    // 按编号顺序添加节点
    public void addByOrder(HeroNode2 heroNode) {
        HeroNode2 temp = head;
        boolean flag = false;

        while (true) {
            if (temp.next == null) {
                break;
            }
            if (temp.next.no > heroNode.no) {
                break;
            } else if (temp.next.no == heroNode.no) {
                flag = true;
                break;
            }
            // 后移指针
            temp = temp.next;
        }

        if (flag) {
            System.out.printf("要插入节点的编号【%d】已存在,无法新增\n", heroNode.no);
        } else {
            heroNode.pre = temp;
            heroNode.next = temp.next;
            // 如果下一个节点为空,不执行下面代码,否则空指针
            if(temp.next != null){
                temp.next.pre = heroNode;
            }
            temp.next = heroNode;

        }
    }

    // 修改
    public void update(HeroNode2 heroNode) {
        // 辅助指针
        HeroNode2 temp = head.next;
        if (temp == null) {
            System.out.println("链表为空");
            return;
        }

        // 标识符,true表示找到需要修改的节点
        boolean flag = false;

        while (true) {
            // 遍历到最后
            if (temp == null) {
                break;
            }
            if (temp.no == heroNode.no) {
                flag = true;
                break;
            }

            // 指针后移
            temp = temp.next;
        }

        if (flag) {
            temp.name = heroNode.name;
            temp.nickname = heroNode.nickname;
        } else {
            System.out.printf("编号为【%d】的节点为找到,无法修改\n", heroNode.no);
        }
    }


    // 删除
    // 说明
    // 1.对于双向链表,可以直接找到要删除的节点
    // 2.找到后,自我删除
    public void delete(int no) {
        // 判断当前链表是否为空
        if (head.next == null) {
            System.out.println("链表为空,无法删除");
            return;
        }

        HeroNode2 temp = head.next;
        // 标识符,true 表示找到要删除的节点
        boolean flag = false;

        while (true) {
            // 遍历到最后节点的next
            if (temp == null) {
                break;
            }

            if (temp.no == no) {
                flag = true;
                break;
            }

            // 指针后移
            temp = temp.next;
        }

        if (flag) {
            temp.pre.next = temp.next;
            // 如果是最后一个节点,不需要执行下面一句代码,否则空指针
            if (temp.next != null) {
                temp.next.pre = temp.pre;
            }
        } else {
            System.out.printf("编号为【%d】的节点为找到,无法删除\n", no);
        }
    }

}

class HeroNode2 {
    public int no;
    public String name;
    public String nickname;
    // 指向下一个节点
    public HeroNode2 next;
    // 指向上一个节点
    public HeroNode2 pre;

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/142581.html

(0)

相关推荐

发表回复

登录后才能评论