双向链表——Java实现

双向链表

 

链表是是一种重要的数据结构,有单链表和双向链表之分;本文我将重点阐述不带头结点的双向链表:

不带头结点的带链表

我将对双链表的增加和删除元素操作进行如下解析

1.增加元素(采用尾插法)

(1)链表为空

     新建结点,将头结点first和尾节点last都指向新建结点,尾节点的next指向空。

 

空链表增加元素

(2)链表非空

     先定义一个临时的结点temp保存当前的尾节点,将尾节点last指向新建结点,并将last的prev指向temp,temp的next指向last.

非空链表增加元素

 

2.删除指定下标的元素

我将分以下三种情况进行讨论

(1)要删除元素为头结点

 用node保存当前头结点first,并将头结点first指向first.next且将现在的first.prev置为空,将node.的next、data分别置为空。

 

 

 

 删除头结点

(2)要删除元素为尾节点

      用节点node保存当前的尾节点,将last指向当前尾节点的前一个节点last.prev,并将现last.next置为空,将以前的last即node节点的prev和data置空。

  

删除尾结点

(3)要删除元素为中间节点

      用节点node保存要删除的节点,并将要删除节点的前一个节点的next指向要删除节点的下一个节点;要删除节点的下一个节点的prev指向要删除节点的还是那个一个节点;即node.prev. next = node.next;node.next.prev = node.prev。并将要删除节点的prev、next及data置为null.

 

删除中间结点

 

 

  1 package Struct;
  2  
  3 interface Link{
  4     void add(Object obj);
  5     boolean remove(int index);
  6     boolean contain(Object obj);
  7     int indexOf(Object obj);
  8     boolean set(int index,Object obj);
  9     Object get(int index);
 10     int length();
 11     void clear();
 12     Object[] toArray();
 13     void printArray(Object[] obj);
 14     void printLink();
 15 }
 16 class Factory{
 17     private Factory(){}
 18     public static Link getLinkInstance(){
 19         return new LinkImpl();
 20     }
 21 }
 22 class LinkImpl implements Link{
 23     private Node first;
 24     private Node last;
 25     private int size;
 26     private class Node{
 27         private Node prev;
 28         private Node next;
 29         private Object data;
 30         public Node(Object data){
 31             this.data = data;
 32         }
 33     }
 34     public void add(Object obj) {
 35         //要插入元素为空
 36         if(obj == null){
 37             return;
 38         }
 39         Node node = new Node(obj);
 40         //空链表
 41         if(first == null){
 42             first = last = node;
 43             first.next = null;
 44             size++;
 45         }else{
 46         //非空链表(尾插)
 47             Node temp = this.last;
 48             temp.next = node;
 49             last = node;
 50             last.prev = temp;
 51             size++;
 52         }
 53     }
 54     //删除
 55     public boolean remove(int index) {
 56         //指定下标不合法
 57         if(index >= size){
 58             return false;
 59         }
 60         Node node = first;
 61         //要删除的节点为头结点
 62         if(index == 0){
 63             first = node.next;
 64             first.prev = null;
 65             node.prev = node.next = null;
 66             node.data = null;
 67             size--;
 68             return true;
 69         }
 70         //要删除节点为尾节点
 71         if(index == size-1){
 72             Node node1 = last;
 73             last = node1.prev;
 74             last.next = null;
 75             node1.prev = node1.next = null;
 76             node1.data = null;
 77             size--;
 78             return true;
 79         } 
 80         //要删除节点为中间节点
 81             Node node3 = get(index);
 82             node3.prev.next = node3.next;
 83             node3.next.prev = node3.prev;
 84             node3.prev = node3.next = null;
 85             node3.data = null;
 86             size--;
 87             return true;
 88     }
 89     //查看元素是否包含在链表中
 90     public boolean contain(Object obj) {
 91         //空链表
 92         if(first == null&&first.next==null){
 93             return false;
 94         }
 95         for(Node node = first;node!=null;node=node.next){
 96             if(node.data==obj){
 97                 return true;
 98             }
 99         }
100         return false;
101     }
102     //求取元素obj的下标
103     public int indexOf(Object obj) {
104         Node node  = first;
105         int signal = 0;
106         //空链表
107         if(first== null&& first.next == null){
108             return -1;
109         }else{
110             for(node = first;node!=null;node=node.next){
111                 if(node.data == obj){
112                     return signal;
113                 }
114                 signal++;
115             }
116         }
117         return signal;
118     }
119     //修改index处的值为obj
120     public boolean set(int index, Object obj) {
121         //指定位置不存在
122         if(index<0||index >= size){
123             return false;
124         }
125         //指定下标超过链表长度
126         if(index >= size){
127             return false;
128         }
129         Node node = first;
130         //若链表头结点是要修改的元素
131         if(node == get(index)){
132             node.data = obj;
133         }
134         Object getObject = get(index);
135         for(node = first;node !=null;node=node.next){
136             if( getObject == node){
137                 node.data = obj;
138             }
139         }
140         return true;
141     }
142     //取得index处的元素
143     public Node get(int index) {
144         if(first==null&&first.next==null){
145             return null;
146         }
147         //要查找下标不在范围内
148         if(index >= size){
149             return null;
150         }
151         Node node = first;
152         //要查找元素在中间元素的左侧
153         if(index >=0 && index <= (index<<1)){
154             for(int i = 0;i <= index - 1;i++){
155                 if(i == index){
156                     return node;
157                 }
158                 node =node.next;
159             }
160         }
161         else if(index > (index<<1)){
162         //要查找元素在中间元素的右侧
163             for(int i = index; i < size-1;i++){
164                 if(i == index){
165                     return node;
166                 }
167                 node = node.next;
168             }
169         }
170             return node;
171     }
172     //求链表长度
173     public int length() {
174         //空链表
175         if(first == null){
176             return 0;
177         }
178         return this.size;
179     }
180     //清空链表
181     public void clear() {
182  
183         Node node = first;
184         if(first == null && first.next == null){
185             return;
186         }
187         for(node = first.next;node!=null;){
188             Node temp = node;
189             node.prev = node.next = null;
190             node.data = null;
191             node = node.next;
192             size--;
193         }
194         first.next = null;
195         first.data = null;
196         size--;
197     }
198     //将链表转换成Object数组
199     public Object[] toArray() {
200         //空链表
201         if(first == null && first.next == null){
202             return null;
203         }else{
204             Object[] linkObject = new Object[this.size];//向上转型
205             Node node = first;
206             for(int i = 0;i<size;i++){    
207                 linkObject[i] = node.data;
208                 node = node.next;
209                 }
210             return linkObject;
211         }
212     }
213     //打印Object数组
214     public void printArray(Object[] obj){
215         for(int i = 0;i < obj.length;i++){
216             System.out.print(obj[i]+" <-> ");
217         }
218     }
219     //打印链表
220     public void printLink() {
221         Node node = first;
222         for(node = first;node!=null;node=node.next){
223             System.out.print(node.data+" <——> ");
224         }
225         System.out.println();
226     }
227     
228 }
229 public class DoubleLinkList {
230     public static void main(String[] args) {
231         Link link = Factory.getLinkInstance();
232         System.out.println("\n"+"=================以下为add测试函数===================");
233         link.add("我是开始位置");
234         link.add("第一名");
235         link.add("第二名");
236         link.add("第三名");
237         link.add("我是结束位置");
238         System.out.println("\n"+"===============以下为printLink测试函数===============");
239         link.printLink();
240         System.out.println("\n"+"===============以下为indexOf测试函数================");
241         System.out.println(link.indexOf("第二名"));
242         System.out.println(link.indexOf("我是结束位置"));
243         System.out.println("\n"+"===============以下为contain测试函数================");
244         System.out.println(link.contain("我是结束位置"));
245         System.out.println(link.contain("hahh"));
246         System.out.println("\n"+"===============以下为get测试函数================");
247         System.out.println(link.get(0));
248         System.out.println(link.get(4));
249         System.out.println(link.get(2));
250         System.out.println(link.get(8));
251         System.out.println("\n"+"===============以下为length测试函数================");
252         System.out.println(link.length());
253         System.out.println("\n"+"===============以下为set测试函数===================");
254         System.out.println(link.set(0, "我是特等奖"));
255         link.printLink();
256         System.out.println("\n"+"===============以下为toArray测试函数===================");
257         Object[] linkObj = link.toArray();
258         System.out.println("\n"+"===============以下为printArray测试函数===================");
259         link.printArray(linkObj);
260         System.out.println("\n"+"===============以下为remove测试函数===================");
261         //删除尾节点
262         System.out.println(link.remove(4));
263         link.printLink();
264         //删除头结点
265         System.out.println(link.remove(0));
266         link.printLink();
267         //删除中间节点
268         System.out.println(link.remove(1));
269         link.printLink();
270         System.out.println(link.length());
271         System.out.println("\n"+"===============以下为clear测试函数===================");
272         link.clear();
273         System.out.println(link.length());
274     }
275 }
View Code

测试结果:

 

posted @ 2020-03-29 21:53  edda_huang  阅读(473)  评论(0编辑  收藏  举报