双向链表的实现

   链表一般有单向链表,双向链表和双向循环链表三种

  双向链表的每一个结点有着三个主要部分:1,存储数据的数据域   2,存储前指针的指针域   3,存储后指针的指针域 

  

  

 

 

  1.MyList接口定义功能

 1 public interface MyList<T>{
 2     //新增一个元素
 3     void add(T element);
 4     //删除与输入元素相同的元素
 5     void delete(T element);
 6     //根据索引删除元素
 7     void delete(int index);
 8     //更新元素
 9     void update(int index,T newelement);
10     //查询1
11     boolean contains(T element);
12     
13     T at(int index);
14     
15     int indexOf(T element);
16 }

  2.ListNode结点类

 1 public class ListNode<T> {
 2       T data;    
 3       ListNode pre; //前驱结点
 4       ListNode next; //后驱结点
 5     
 6     public ListNode()
 7     {
 8         
 9     }
10     public ListNode(T element)
11     {
12         this.data=element;
13     }
14     
15     
16 }

  3.DoubleLinkedList类

  1 public class DoubleLinkedList<T> implements MyList<T>{
  2     private ListNode<T> first=new ListNode<T>(); //头结点哑元
  3     private ListNode<T> last=new ListNode<T>(); //尾结点哑元
  4     private int size=0; //记录添加的个数
  5     
  6     public DoubleLinkedList()
  7     {
  8         first.next=last;
  9         last.pre=first;
 10     }
 11     
 12     @Override
 13     public void add(T element) {
 14         ListNode<T> newNode=new ListNode<T>(element);
 15         //注意添加结点的顺序
 16         last.pre.next=newNode;
 17         newNode.pre=last.pre;
 18         newNode.next=last;
 19         last.pre=newNode;
 20         size++;
 21     }
 22 
 23     @Override
 24     public void delete(T element) {
 25         ListNode<T> p=first.next; //复制一个头结点,以免后面操作影响头结点
 26         while(p!=null)
 27         {
 28             if(p.data.equals(element))
 29             {
 30                 p.pre.next=p.next;
 31                 p.next.pre=p.pre;
 32                 size--;
 33                 return ;
 34             }
 35             p=p.next;
 36         }
 37         
 38     }
 39 
 40     @Override
 41     public void delete(int index) {
 42         int i=0;
 43         ListNode<T> p=first.next;
 44         while(p!=last)
 45         {
 46             if(i==index)
 47             {
 48                 p.pre.next=p.next;
 49                 p.next.pre=p.pre;
 50                 p.pre=null;
 51                 p.next=null;
 52                 size--;
 53                 return ;
 54             }
 55             p=p.next;
 56             i++;
 57         }
 58         
 59     }
 60 
 61     @Override
 62     public void update(int index, T newelement) {
 63         int i=0;
 64         ListNode<T> p=first.next;
 65         while(p!=null)
 66         {
 67             if(i==index)
 68             {
 69                 p.data=newelement;
 70             }
 71             p=p.next;
 72             i++;
 73         }
 74         
 75         
 76     }
 77 
 78     @Override
 79     public boolean contains(T element) {
 80         return indexOf(element)>=0;
 81     }
 82 
 83     @Override
 84     public T at(int index) {
 85         int i=0;
 86         ListNode<T> p=first.next;
 87         while(p!=null)
 88         {
 89             if(i==index)
 90             {
 91                 return (T) p.data;
 92             }
 93             p=p.next;
 94             i++;
 95         }
 96         return null;
 97     }
 98 
 99     @Override
100     public int indexOf(T element) {
101         int i=0;
102         ListNode<T> p=first.next;
103         while(p!=null)
104         {
105             if(p.data.equals(element))
106             {
107                 return i;
108             }
109             p=p.next;
110             i++;
111         }
112         return -1;
113     }
114     
115     @Override
116     public String toString()
117     {
118         StringBuilder sb=new StringBuilder("[");
119         ListNode<T> p=first.next;
120         while(p!=last)
121         {
122             sb.append(p.data+(p.next!=last?",":""));
123             
124             p=p.next;
125         }
126         sb.append("]");
127         return sb.toString();
128     }
129 
130     public int getSize()
131     {
132         return this.size;
133     }
134     
135 
136 }

 

单向链表:只有一个指向下一个节点的指针。

优点:单向链表增加删除节点简单。遍历时候不会死循环;

缺点:只能从头到尾遍历。只能找到后继,无法找到前驱,也就是只能前进。

适用于节点的增加删除。

 

双向链表:有两个指针,一个指向前一个节点,一个后一个节点。

优点:可以找到前驱和后继,可进可退;

缺点:增加删除节点复杂,多需要分配一个指针存储空间。

适用于需要双向查找节点值的情况。

posted @ 2018-12-26 13:30  Spider&Man  阅读(797)  评论(0编辑  收藏  举报