java实现双链表结构与基本数据操作

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HeadingAlong/article/details/54783321

在上篇博客当中介绍单链表的实现。在单链表的基础上设计双链表并不会太难,只需要理解双链表的结构,是如何进行数据操作的,即可完成代码的设计。

何为双链表

双链表的每个数据节点中都有两个引用,分别指向前一个节点和后一个节点。所以,从双向链表中的任意一个结点开始,都可以方便的进行数据查找。

代码实现

注意:该链表同样不允许放入相同元素
- 双链表的节点

class Node{
        //节点属性
        private T date;
        private Node next;
        private Node prev;
        public Node(T date){
            this.date = date;
        }
    }
  • 从尾部添加数据 addLast
public boolean addLast(T date){
        boolean flag = false;
        if(!existNode(date)){
            //将数据封装为节点添加进来
            Node newNode = new Node(date);//新建新节点

            //判断链表有没有数据
            if(head==null){//说明链表为空
                //直接将新节点作为头结点和尾节点
                head = newNode;
                tail = newNode;
            }else{//链表不为空,从尾部开始添加
                //新节点的prev指向尾节点,
                newNode.prev = tail;
                //尾节点的next指向新节点
                tail.next = newNode;
                //将尾节点指向新建节点
                tail = newNode;
            }
            flag = true;
        }
        return flag;
    }
  • 从头添加数据 addFirst
public boolean addFirst(T date){
        boolean flag = false;
        if(!existNode(date)){//确定链表中没有即将添加的节点
            //将数据封装为节点添加进来
            Node newNode = new Node(date);//新建新节点

            //判断链表有没有数据
            if(head==null){//说明链表为空
                //直接将新节点作为头结点和尾节点
                head = newNode;
                tail = newNode;
            }else{//链表不为空,从头部开始添加
                //新节点的prev置为null
                newNode.prev = null;
                //新节点的next指向头结点
                newNode.next = head;
                //将头节点指向新建节点
                head = newNode;
            }
            flag = true;
        }else{
            throw new RuntimeException("数据在链表中已经存在!");
        }
        return flag;
    }
  • 有序添加数据
public boolean addOrdered(T date){
        boolean flag = false;
        //确认链表中没有该数据
        if(!existNode(date)){
            //找到比该链表大的节点
            Node biggerNode = findBiggerNode(date);
            if(biggerNode==null){//没有找到比新节点大的节点
                //将该节点添加在尾部
                this.addLast(date);
            }else{//找到了比该节点大的节点,将该节点放在大节点的前面
                Node prev = biggerNode.prev;//找到大节点前面的节点
                if(prev==null){//前面节点为空,说明该大节点是头结点,将新节点从头添加
                    addFirst(date);
                }else{//前面节点不为空,
                    Node newNode = new Node(date);//创建新节点
                    prev.next = newNode;//将前面节点的next指向新节点
                    newNode.prev = prev;//将新节点的prev指向前面节点
                    newNode.next = biggerNode;//将新节点的next指向大节点
                    biggerNode.prev = newNode;//将大节点的prev指向新节点
                }


            }
            flag = true;
        }
        return flag;
    }
  • 更新数据 update
public boolean update(T old,T newDate){
        boolean flag = false;
        Node target = findNode(old);//找到要更新的节点(此时拿到的是节点的引用)
        if(target==null){
            throw new RuntimeException("没有此数据");
        }else{//确定节点已经存在
            Node existNode = findNode(newDate);
            if(existNode!=null){//确定数据唯一
                throw new RuntimeException("该数据已经存在,请使用不存在的数据");
            }
            //修改该数据的date值
            target.date = newDate;
            flag = true;

        }
        return flag;
    }
  • 删除数据 remove
public boolean remove(T date){
        boolean flag = false;
        //找到该节点
        Node target = findNode(date);
        try {
            if(target!=null){

                if(target.next==null&&target.prev==null){//既是头结点又是尾节点
                    head = null;
                    tail = null;
                }
                else if(target.next == null){//说明该节点是尾节点
                    //将该节点的上一个节点的next置为null
                    target.prev.next = null;
                    //将该节点的上一个节点作为尾节点
                    tail = target.prev;
                }else if(target.prev == null){//说明该节点是头节点
                    //将该节点的下一个节点的prev置为null
                    target.next.prev = null;
                    //将该节点的下一个节点作为头结点
                    head = target.next;
                }else{//该节点是中间节点
                    //将该节点的next节点的prev指向该节点的prev节点
                    target.next.prev = target.prev;
                    //将该节点的prev节点的next指向该节点的next节点
                    target.prev.next = target.next;
                }
                flag = true;
            }
        } catch (Exception e) {
            throw new RuntimeException("元素不存在");
        }
        return flag;
    }

猜你喜欢

转载自blog.csdn.net/HeadingAlong/article/details/54783321