zoukankan      html  css  js  c++  java
  • 手写LinkedList实现(基于双链表)

        上次我通过单链表实现了List接口,但是单链表的结构只可以允许从前到后遍历获取数据显的不是那么的方便,在java中一般使用双向链表来获取存储数据,双向链表中的每个节点除了要保存它的下一个节点对象的引用以外还会保存一个它前一个节点对象的引用,这样就可以实现双向查找数据。

        首先定义个新的节点接口:

    public class DLNodel implements Node{
        private Object element;
        private DLNodel next;
        private DLNodel pre;
    
    
        @Override
        public Object getData() {
            return element;
        }
    
        @Override
        public void setDate(Object data) {
            element = data;
        }
    
        public DLNodel getNext() {
            return next;
        }
    
        public void setNext(DLNodel next) {
            this.next = next;
        }
    
        public DLNodel getPre() {
            return pre;
        }
    
        public void setPre(DLNodel pre) {
            this.pre = pre;
        }
    }

    在这个接口里面相比单链表节点添加了pre属性用来保存前一个节点对象的引用。List接口的实现:

    public class LinkedDList<E> implements List<E>{
    
        private DLNodel head;  //链表头
        private int size;
        private DLNodel tail;  //链表尾
    
        public LinkedDList() {
            head = new DLNodel();
            tail = new DLNodel();
            head.setNext(tail);
            tail.setPre(head);
        }
    
        private DLNodel getNode(int index){
            DLNodel node = null;
            if(index>(size>>1)) {
                //从后向前找
                int lastindex = size - 1 - index;
                node = tail;
                for (; lastindex > 0; lastindex--) {
                    node = node.getPre();
                }
            }else{
                node = head;
                for(;index>0;index--){
                    node = node.getNext();
                }
            }
            return node;
        }
    
        @Override
        public int size() {
            return size;
        }
    
        @Override
        public boolean isEmpty() {
            return size==0;
        }
    
        @Override
        public boolean contains(Object o) {
            DLNodel node = head;
            if(head!=null){
                while (head!=null){
                    if(head.getData().equals(o)){
                        return true;
                    }
                    head = head.getNext();
                }
            }
            return false;
        }
    
        @Override
        public boolean add(E e) {
            if(size==0){
                head.setDate(e);
                size++;
                return true;
            }else if(size==1){
                tail.setDate(e);
                size++;
                return true;
            }else{
                DLNodel oldtail = tail;
                DLNodel newtail = new DLNodel();
                newtail.setDate(e);
                oldtail.setNext(newtail);
                newtail.setPre(oldtail);
                tail = newtail;
                size++;
                return true;
            }
        }
    
        @Override
        public boolean remove(Object o) {
            int index = indexOf(o);
            E e  = remove(index);
            return e!=null;
        }
    
        @Override
        public E get(int index) {
            if(index<0||index>size-1){
                return null;
            }
            DLNodel node = getNode(index);
            if(node!=null){
                return (E)node.getData();
            }else{
                return null;
            }
        }
    
        @Override
        public E set(int index, E element) {
            if(index<0||index>size-1){
                return null;
            }
            E e = null;
            DLNodel node = getNode(index);
            if(node!=null){
               e =  (E)node.getData();
               node.setDate(element);
            }
            return e;
        }
    
        @Override
        public void add(int index, E element) {
            if(index<0||index>size-1){
                throw new RuntimeException("索引越界");
            }
            if(index==size){
                add(element);
            }else{
                if(index==0){
                    DLNodel oldnode = head;
                    DLNodel newtail = new DLNodel();
                    oldnode.setPre(newtail);
                    newtail.setDate(element);
                    newtail.setNext(oldnode);
                    head = newtail;
                    size++;
                }else{
                    DLNodel node = getNode(index);
                    DLNodel newnode = new DLNodel();
                    newnode.setDate(element);
                    newnode.setPre(node);
                    newnode.setNext(node.getNext());
                    node.getNext().setPre(newnode);
                    node.setNext(newnode);
                    size++;
                }
            }
        }
    
        @Override
        public E remove(int index) {
            if(index<0||index>size-1){
                throw new RuntimeException("索引越界");
            }
            if(index==0){
               //移除头
               E result =  (E)head.getData();
               head.getNext().setPre(null);
               head = head.getNext();
               size--;
               return result;
            }else if(index==size-1){
                //移除尾
                E result =  (E)tail.getData();
                tail.getPre().setNext(null);
                tail = tail.getPre();
                size--;
                return result;
            }else{
                DLNodel node = getNode(index);
                E result =  (E)node.getData();
                node.getPre().setNext(node.getNext());
                node.getNext().setPre(node.getPre());
                size--;
                return result;
            }
    
        }
    
        @Override
        public int indexOf(Object o) {
            DLNodel p = head;
            int index = 0;
            while (p.getNext()!=null){
                if(p.getData().equals(o)){
                    return index;
                }
                p = p.getNext();
                index++;
            }
            return -1;
        }
    
        @Override
        public int lastIndexOf(Object o) {
            DLNodel p = head;
            int index = size-1;
            while (p.getNext()!=null){
                if(p.getData().equals(o)){
                    return index;
                }
                p = p.getNext();
                index--;
            }
            return -1;
        }
    }

    双向链表因为可以双向遍历查找数据所以查询数据的效率要比单向链表高,但是因为双向链表的节点之间的关系要比单向链表复杂,所以在添加和删除时的效率不如单向列表。总体来讲双向链表的性能要比单向链表高。

  • 相关阅读:
    调试PHP如何让浏览器提示错误
    接口的理解
    linux中的curl
    linux后台执行命令:&和nohup
    php定界符<<<EOF讲解
    有关字符集问题
    设置disabled属性
    PHP魔术常量
    phpstorm-有关设置
    php常用函数
  • 原文地址:https://www.cnblogs.com/suyang-java/p/12030750.html
Copyright © 2011-2022 走看看