美文网首页
双端链表的实现

双端链表的实现

作者: 吉他手_c156 | 来源:发表于2020-06-07 14:19 被阅读0次

话不多说上代码

/**
 * 双端链表
 */
public class DoublePointLinkedList<T> {

    // 链表中的每一个节点
    private class Node{
        private T data;  // 链表中的数据
        private Node next; // 下一个节点
        public Node(T data){
            this.data = data;
        }
    }

    private Node head; // 头节点
    private Node tail; // 尾节点
    private int size; // 链表长度
    // 初始化
    public DoublePointLinkedList(){
        this.head = null;
        this.tail = null;
        this.size = 0;
    }

    // 在链表头新增节点
    public boolean addHead(T data){
        // 构建新节点
        Node newNode = new Node(data);
        // 如果当前链表为空  将头节点和尾节点都指向新增的节点
        if(this.size == 0){
            this.head = newNode;
            this.tail = newNode;
        }else{
            // 将新创建节点的 next 节点指向 head 头节点
            newNode.next = this.head;
            // 再将 head 头节点指向 新创建节点
            this.head = newNode;
        }
        this.size ++;
        return true;
    }

    // 在链表的尾部新增节点
    public boolean addTail(T data){
        // 构建新节点
        Node newNode = new Node(data);
        // 如果链表为空,将头节点和尾节点都指向新增节点
        if(this.size == 0){
            this.head = newNode;
            this.tail = newNode;
        }else{
            // 由于新增了尾节点链表的节点也必须增加
            // 这里 tail 尾节点 和 head 头节点指向的是同一引用
            // 这一将 tail 的 next 节点设置为 新创建节点
            // 也就相当于在原来链表的基础上再尾部新增了一个节点
            this.tail.next = newNode;
            this.tail = newNode;
        }
        this.size ++;
        return true;
    }

    // 删除头节点 成功返回 删除数据
    public T removeHead(){
        // 如果链表中没有数据
        if(this.size == 0){
            throw new RuntimeException("链表中没有数据");
        }
        // 获取头节点数据
        T t  = this.head.data;
        // 如果链表中只有一条数据
        // 将头节点和尾节点头清空
        if(this.size == 1){
            this.head = null;
            this.tail = null;
        }else{
            // 将头节点 next 节点设置为 head 头节点
            this.head = this.head.next;
        }
        size --;
        return t;
    }

    // 删除尾节点
    public T removeTail(){
        // 如果链表中没有数据
        if(this.size == 0){
            throw new RuntimeException("链表中没有数据");
        }
        // 获取尾节点值
        T t = tail.data;

        // 如果链表中只有一条数据,将 head 集合 tail 都设置为 null
        if(this.size == 1){
            this.head = null;
            this.tail = null;
        }
        Node curr = this.head;  // 表示当前节点
        Node prrvious = this.head;  // 表示当前节点的上一个节点

        // curr 的 next 节点入过不为空说明还没有到最有一个节点
        // 反之已经是最后一个节点了
        while (curr.next != null){
            // 将当前节点的上一个节点指向当前节点
            prrvious = curr;
            // 将当前节点指向为当前节点的下一个节点,直到找到最后一个节点
            curr = curr.next;
        }

        // 走到这里 curr 已经是最后一个节点了,也就是尾节点
        // 删除尾节点,也就是将最后一个节点设置为 null
        // 由于 curr 节点的上一个节点 previous 的 next 节点指向的 curr 节点就是最后一个节点
        // 所以要将 previous 的 next 节点设置为 null
        prrvious.next = null;
        // 设置新的尾节点 将 tail 指向 curr 的上一个节点 previouts 即可
        this.tail = prrvious;
        size --;
        return t;
    }

    // 打印节点信息
    public void display(){
        if(this.size > 0){
            Node curr = this.head;    // 头节点
            int tempSize = this.size; // 链表长度
            while (tempSize > 0){
                // 头节点
                if(curr.equals(this.head)){
                    System.out.print("["+curr.data+"->");
                }else if(curr.next == null){
                    // 最有一个节点
                    System.out.print(curr.data+"]");
                }else {
                    // 其他节点
                    System.out.print(curr.data+"->");
                }
                // 将当前节点指向到 当前节点的 next 下一个节点
                // 直到找最有一个节点
                curr = curr.next;
                tempSize --;
            }
            System.out.println();
        }else{
            // 没有数打印空
            System.out.println("[]");
        }
    }

    public static void main(String[] args) {
        DoublePointLinkedList<String> doublePointLinkedList = new DoublePointLinkedList<String>();
        System.out.println("*****************  在尾部新增节点 *******************");
        doublePointLinkedList.addTail("A");
        doublePointLinkedList.addTail("B");
        doublePointLinkedList.addTail("C");
        doublePointLinkedList.addTail("D");
        doublePointLinkedList.addTail("E");
        // 打印数据
        doublePointLinkedList.display();
        // 新增头节点
        System.out.println("*****************  在头部新增节点 *******************");
        doublePointLinkedList.addHead("9");
        doublePointLinkedList.addHead("8");
        // 打印数据
        doublePointLinkedList.display();
        System.out.println("*****************  在尾部新增节点 *******************");
        // 新增尾节点
        doublePointLinkedList.addTail("F");
        // 打印数据
        doublePointLinkedList.display();

        System.out.println("*****************  删除头节点 *******************");
        // 删除头节点
        doublePointLinkedList.removeHead();
        // 打印数据
        doublePointLinkedList.display();

        System.out.println("*****************  删除尾节点 *******************");
        // 删除尾节点
        doublePointLinkedList.removeTail();
        // 打印数据
        doublePointLinkedList.display();
    }
}

结果

*****************  在尾部新增节点 *******************
[A->B->C->D->E]
*****************  在头部新增节点 *******************
[8->9->A->B->C->D->E]
*****************  在尾部新增节点 *******************
[8->9->A->B->C->D->E->F]
*****************  删除头节点 *******************
删除的头节点=8
[9->A->B->C->D->E->F]
*****************  删除尾节点 *******************
删除的尾节点=F
[9->A->B->C->D->E]

相关文章

  • redis 源码见闻录(二)

    双端链表 双端链表是redis list类型的实现之一,另一种是压缩列表。因为双端链表占的内存比较高,一般都是优先...

  • Java集合类(二)LinkedList源码分析

    LinkedList是一个实现了List接口和Deque接口的双端链表。 其继承关系如下图 这里提到了双端链表,到...

  • 数据结构 | 其二 链表

    冰河winner - 数据结构之链表 2.1 单向链表 数据结构(一) 单链表的实现-JAVA 2.2 双端链表 ...

  • 自己动手写数据结构之双端链表

    双端链表实现 1 定义 双端链表与传统的链表很相似,但是它有一个新增的特性;即对最后一个链结点的引用 2 基本操作...

  • 双端链表的实现

    话不多说上代码 结果

  • LinkedList

    实现: 基于链表的数据结构实现,实现了List和Deque接口,有List和队列的特性,底层实现是一个双端链表,内...

  • 剖析LinkedList

    简介 LinkedList是一个实现了List接口和Deque接口的双端链表。 LinkedList底层的链表结构...

  • Redis底层数据结构之双端链表

    前言 Redis的双端链表是基于双向链表实现的,但传统双向链表存在一些问题,比如获取链表长度需要遍历整个链表,时间...

  • 03_栈stack

    基于双端链表实现内存里的栈区 (和堆对应)后进后出

  • 链表

    链表数据结构 Redis的链表实现是双端链表,每个链表节点由一个listNode结构来表示,每个节点都有一个指向前...

网友评论

      本文标题:双端链表的实现

      本文链接:https://www.haomeiwen.com/subject/ytdctktx.html