下武维周

双向链表的构造(算法4习题1.3.31)

  原题:实现一个嵌套类DoubleNode用来构造双向链表,其中每个节点都含有一个指向前驱元素的引用和一个指向后续元素的引用(如果不存在则为NULL)。为以下任务实现若干静态方法:在表头插入结点、在表尾插入结点、在表头删除结点、在表尾删除结点、在指定结点之前插入新结点、在指定结点之后插入新结点、删除指定结点。

  我写的代码里为了加强程序的模块化、将调用和实现分离,添加另外几个方法,并且没有使用静态方法。

构造类:

  1 package com.lch.Chapter1_3;
  2 
  3 import java.util.Iterator;
  4 
  5 import edu.princeton.cs.algs4.StdOut;
  6 
  7 /**
  8  * 
  9  * @author Lucas.Li
 10  *
 11  * @param <Item>
 12  * 
 13  * @Content 双向链表的构造
 14  */
 15 public class BothwayLinkedListStack<Item> implements Iterable<Item> {
 16 
 17     private int N;
 18     private DoubleNode first;
 19     private DoubleNode last;
 20 
 21     /**
 22      * 
 23      * @author Lucas.Li 构造嵌套类
 24      * 
 25      */
 26     private class DoubleNode {
 27         Item item;
 28         DoubleNode next;
 29         DoubleNode prev;
 30     }
 31 
 32     /**
 33      * 
 34      * @return 链表大小
 35      */
 36     public int size() {
 37         return N;
 38     }
 39 
 40     /**
 41      * 
 42      * @return 链表是否为空
 43      */
 44     public boolean isEmpty() {
 45         return N == 0;
 46     }
 47 
 48     /**
 49      * 在表头添加元素
 50      * 
 51      * @param item
 52      */
 53     public void push(Item item) {
 54         DoubleNode oldFirst = first;
 55         first = new DoubleNode();
 56         first.item = item;
 57         first.next = oldFirst;
 58         first.prev = null;
 59         if (N == 0) {
 60             last = first;
 61         } else {
 62             oldFirst.prev = first;
 63         }
 64         N++;
 65     }
 66 
 67     /**
 68      * 
 69      * @return 表头弹出的元素值
 70      */
 71     public Item pop() {
 72         if (N == 0) {
 73             try {
 74                 throw new Exception("There is none on stack!");
 75             } catch (Exception e) {
 76                 // TODO Auto-generated catch block
 77                 e.printStackTrace();
 78             }
 79         }
 80         Item item = first.item;
 81         first = first.next;
 82         first.prev = null;
 83         N--;
 84         return item;
 85     }
 86 
 87     /**
 88      * 表头添加元素
 89      * 
 90      * @param item
 91      */
 92     public void insertHead(Item item) {
 93         DoubleNode node = new DoubleNode();
 94         node.item = item;
 95         node.prev = null;
 96         node.next = first;
 97         first.prev = node;
 98         first = new DoubleNode();
 99         first = node;
100         N++;
101     }
102 
103     /**
104      * 表尾添加元素
105      * 
106      * @param item
107      */
108     public void insertTail(Item item) {
109         DoubleNode node = new DoubleNode();
110         node.item = item;
111         node.prev = last;
112         node.next = null;
113         last.next = node;
114         last = new DoubleNode();
115         last = node;
116         N++;
117     }
118 
119     /**
120      * 指定结点前插入元素
121      * 
122      * @param item
123      * @param node
124      */
125     public void insertBeforeNode(Item item, DoubleNode node) {
126         if (isFirst(node)) {
127             insertHead(item);
128             N++;
129         } else {
130             DoubleNode newNode = new DoubleNode();
131             newNode.item = item;
132             newNode.prev = node.prev;
133             newNode.next = node;
134             node.prev.next = newNode;
135             node.prev = newNode;
136             N++;
137         }
138     }
139 
140     /**
141      * 指定结点后插入元素
142      * 
143      * @param item
144      * @param node
145      */
146     public void insertAfterNode(Item item, DoubleNode node) {
147         if (isLast(node)) {
148             insertTail(item);
149             N++;
150         } else {
151             DoubleNode newNode = new DoubleNode();
152             newNode.item = item;
153             newNode.prev = node;
154             newNode.next = node.next;
155             node.next.prev = newNode;
156             node.next = newNode;
157             N++;
158         }
159     }
160 
161     /**
162      * 删除指定结点
163      * @param node
164      */
165     public void deleteNode(DoubleNode node){
166         if (isFirst(node)){
167             deleteHead();
168             N--;
169         } else if (isLast(node)) {
170             deleteTail();
171             N--;
172         } else {
173             node.next.prev = node.prev;
174             node.prev.next = node.next;
175             node.prev = null;
176             node.next = null;
177             N--;
178         }
179     }
180 
181     /**
182      * 删除表头元素
183      */
184     public void deleteHead() {
185         if (N == 0) {
186             try {
187                 throw new Exception("There is none on stack!");
188             } catch (Exception e) {
189                 // TODO Auto-generated catch block
190                 e.printStackTrace();
191             }
192         }
193         first = first.next;
194         first.prev = null;
195         N--;
196     }
197 
198     /**
199      * 删除表尾元素
200      */
201     public void deleteTail() {
202         if (N == 0) {
203             try {
204                 throw new Exception("There is none on stack!");
205             } catch (Exception e) {
206                 // TODO Auto-generated catch block
207                 e.printStackTrace();
208             }
209         }
210         last = last.prev;
211         last.next = null;
212         N--;
213     }
214 
215     /**
216      * 
217      * @param m
218      * @return 指定结点(从表头数起第m个结点)
219      */
220     public DoubleNode getNode(int m) {
221         if (m > N) {
222             try {
223                 throw new Exception("Not enough on stack! Return the last one!");
224             } catch (Exception e) {
225                 // TODO Auto-generated catch block
226                 e.printStackTrace();
227             }
228             return last;
229         }
230         DoubleNode node = new DoubleNode();
231         node = first;
232         int i = 1;
233         while (i < m) {
234             node = node.next;
235             i++;
236         }
237         return node;
238     }
239 
240     /**
241      * 
242      * @param node
243      * @return 结点元素的值
244      */
245     public Item getItem(DoubleNode node) {
246         return node.item;
247     }
248 
249     /**
250      * 
251      * @return 链表首结点
252      */
253     public DoubleNode getFirst() {
254         return first;
255     }
256 
257     /**
258      * 
259      * @return 链表尾结点
260      */
261     public DoubleNode getLast() {
262         return last;
263     }
264 
265     /**
266      * 
267      * @param node
268      * @return 判断结点是否为首结点
269      */
270     public boolean isFirst(DoubleNode node) {
271         if (node.prev == null) {
272             return true;
273         } else {
274             return false;
275         }
276     }
277 
278     /**
279      * 
280      * @param node
281      * @return 判断结点是否为尾结点
282      */
283     public boolean isLast(DoubleNode node) {
284         if (node.next == null) {
285             return true;
286         } else {
287             return false;
288         }
289     }
290 
291     /**
292      * 遍历器
293      */
294     @Override
295     public Iterator<Item> iterator() {
296         // TODO Auto-generated method stub
297         return new ListIterator();
298     }
299 
300     /**
301      * 扩展实现遍历器
302      * 
303      * @author Administrator
304      *
305      */
306     private class ListIterator implements Iterator<Item> {
307 
308         private DoubleNode current = first;
309 
310         @Override
311         public boolean hasNext() {
312             // TODO Auto-generated method stub
313             return current != null;
314         }
315 
316         @Override
317         public Item next() {
318             // TODO Auto-generated method stub
319             Item item = current.item;
320             current = current.next;
321             return item;
322         }
323 
324         @SuppressWarnings("unused")
325         public DoubleNode getCurrent() {
326             return current;
327         }
328 
329     }
330 
331 }

测试类:

 1 package com.lch.MyTest;
 2 
 3 import java.util.Iterator;
 4 
 5 import com.lch.Chapter1_3.BothwayLinkedListStack;
 6 import com.lch.Chapter1_3.LinkedListStack;
 7 
 8 import edu.princeton.cs.algs4.StdOut;
 9 
10 /**
11  * 双向链表测试类
12  * @author Administrator
13  *
14  */
15 public class DoubleNodeTest {
16 
17     public static void init_01() {
18         BothwayLinkedListStack<String> blls = new BothwayLinkedListStack<String>();
19         String[] strs = "abcdefg".split("");
20         for (int i = 0; i < strs.length; i++) {
21             blls.push(strs[i]);
22         }
23         iteratorList(blls);
24         blls.insertHead("head");
25         iteratorList(blls);
26         blls.insertTail("tail");
27         iteratorList(blls);
28         blls.deleteHead();
29         iteratorList(blls);
30         blls.deleteTail();
31         iteratorList(blls);
32         blls.insertBeforeNode("before", blls.getNode(2));
33         iteratorList(blls);
34         blls.insertAfterNode("after", blls.getNode(2));
35         iteratorList(blls);
36         blls.deleteNode(blls.getNode(2));
37         iteratorList(blls);
38     }
39 
40     public static <Item> void iteratorList(BothwayLinkedListStack<Item> stack) {
41         Iterator<Item> iterator = stack.iterator();
42         while (iterator.hasNext()) {
43             StdOut.print(iterator.next() + " ");
44         }
45         StdOut.println();
46     }
47 
48     public static void main(String[] args) {
49         init_01();
50     }
51 
52 }

结果:

posted on 2018-12-11 12:54  北岸探花  阅读(390)  评论(0编辑  收藏  举报

导航