【双向链表】数据结构详解

目录

简介:

代码简单模拟双向列表(详细注解)


简介:

双向链表的应用:linkedList

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

好处:插入、删除的速度比ArrayList扩容来的快的多。

缺点:对于随机访问,查询速度慢

代码简单模拟双向列表(详细注解)

结果图例:

注意:

        1.遍历是按照指针指向节点的方式遍历的

        2.插入、删除是把指向节点和下节点的指向改变就完成插入和删除了

        3.我自己改写的有参构造器,相当于新增功能

package com.gao.test.collection.linkedList;

/**
 * @Author lie
 * @Description 简单介绍双向链表结构
 */
public class DoubleLinkedList {
    public static void main(String[] args) {

        //第一节点
        Node first = new Node();
        //最后节点
        Node last = new Node();
        /**
         * 模拟双向链表
         * 创建3个节点数据
         */
        //这个相当于在链表尾部添加节点,加进来的节点注意头节点和为节点的位置
        // (这个应该封装个方法判断是不是第一个加入,因为简单介绍就不封装了,直接指向了)
        Node one = new Node("节点数据1",null,null);
        first = one;
        Node two = new Node("节点数据2",one,null);
        last = two;
        Node three = new Node("节点数据3",two,null);
        //后面新加的都改变最后指针的位置
        last = three;

        //正序遍历(第一节点的指针,正向遍历所有节点)
        System.out.println("====正序遍历====");
        forwardIterator(first);
        //倒序遍历(最后节点的指针,倒序遍历所有节点)
        System.out.println("====倒序遍历====");
        reverseIterator(last);

        //2、3节点中间插入(我有参构造器已经考虑进去了,直接传入前后节点,就是中间插入)
        Node haha = new Node("哈哈,插入节点",two,three);

        //遍历一下
        System.out.println("====正序遍历插入后的节点====");
        forwardIterator(first);

        //删除角标置顶位置的节点
        deleteNode(two);

        //遍历一下
        System.out.println("====正序遍历删除后的节点====");
        forwardIterator(first);


    }

    /**
     * 删除节点
     * @param index 节点位置
     */
    private static void deleteNode(Node index) {
        //存储一下当前节点的值
        final Object item = index.item;
        final Node prev = index.pre;
        final Node next = index.next;

        //前一个节点的next连接到下一个节点上(这里不判断pre、next为空的情况,想看可以追原码看)
        prev.next = next;
        index.pre = null; //指向空

        //后一个节点的pre连接到前一个节点上(这里不判断pre、next为空的情况,想看可以追原码看)
        next.pre = prev;
        index.next = null; //指向空

        index.item = null; //把数据置空,gc处理掉垃圾数据
    }

    /**
     * 正向遍历的方法
     * @param first 第一节点
     */
    private static void forwardIterator(Node first) {
        while (null != first) {
            System.out.println(first);
            first = first.next;
        }
    }

    /**
     * 反向遍历的方法
     * @param last 最后节点
     */
    private static void reverseIterator(Node last) {
        while (null != last) {
            System.out.println(last);
            last = last.pre;
        }
    }
}


class Node{
    /**
     * 存储节点数据
     */
    public Object item;
    /**
     * 链表的前一个节点
     */
    public Node pre;
    /**
     * 链表的下一个节点
     */
    public Node next;

    public Node() {
    }

    /**
     * 有参构造器(添加节点)
     * @param item object
     */
    public Node(Object item,Node pre,Node next) {
        this.item = item;
        //链前面节点
        this.pre = pre;
        //连接后面节点
        this.next = next;
        //如果不为空,说明有前面的节点(说明是中间或者是尾部插入操作),把前面节点的next连接这个新增的节点
        if(null != pre){
            pre.next = this;
        }
        //如果不为空,说明有后面的节点(说明是中间或者头部插入操作),把后面节点的pre连接这个新增的节点
        if (null != next) { next.pre = this;
        }
    }

    @Override
    public String toString() {
        return item.toString();
    }
}

说明:

        简单模拟双向列表,健壮性不足,最好可以直接新建linkedList对象,追源码看。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值