In the previous article, I worshipped BigInteger and thought it was very complicated. As a result, the source code of jdk is a 3000-line java file. Therefore, it is necessary to write some underlying things on the right.
The first is to practice, the second is to understand java's way of thinking, and the third is to compare what the successors of C ++ have abandoned.
The main points are all written in comments:
/* Simulate listtest. java -- simulate a double-chain table in the C style. 1. head-> func (head) is changed to head. func () through this (). 2. C macro/template --> generic, add public to method Header
> Public
> Although it can be compiled, other methods of this class cannot be called. By searching for keywords: "Comparable generic type", the correct method is DNode when defining generic classes.
Change to DNode
> Extends indicates a limit. * Author ludi 2014.03 */class DNode
> {Public T val; public DNode
Next, prev;/* The linked list is usually bidirectional and makes some operations easier */public DNode () {/* to create a linked list header. Generally, val is left blank, of course, we can also use it as the number of linked lists */val = null; next = prev = this;} public DNode (T item) {val = item; next = prev = this; /* why is it not null? * The purpose is to form a closed loop. If the last node of the linked list is tail, * head-> prev = tail; tail. next = head. * The advantage of the closed loop is that the subsequent insert/delete operations do not have to judge whether the pointer is null */}/* because the parameter is generic
You have to put all the linked list methods on DNode.
*/Public String toString () {String str = "[";/* traversal template: Count, search,... */DNode
Curr = this. next; while (curr! = This) {if (curr. val! = Null) str + = curr. val. toString () + ","; curr = curr. next;} str + = "]"; return str;} public DNode
IndexOf (int idx) {DNode
Curr = this. next; for (; curr! = This; curr = curr. next) {if (0 = idx) break; -- idx;} return (0 = idx )? Curr: null;} public void insertAfter (DNode
Node, DNode
X) {x. next = node. next; node. next. prev = x; x. prev = node; node. next = x;} public void insertTail (DNode
X) {insertAfter (this. prev, x);} public DNode
DeleteAfter (DNode
Node) {DNode
X = node. next; x. next. prev = node; node. next = x. next; return x;}/* The above several methods are basic operations. For stacks used as general linked lists and linked lists, the queue is sufficient. * The following is just an exercise question */public void reverseList () {/* linked list flip, similar to array flip. (What if it is a single-chain table ?) */DNode
First = this. next, last = this. prev; while (first! = Last) {T val = first. val; first. val = last. val; last. val = val; first = first. next; last = last. prev;} public void deleteAll () {/* clear linked list */DNode
X = null; while (this. next! = This) {x = deleteAfter (this); x = null ;}} public DNode
InsertionSort () {/* incremental sorting */DNode
List = new DNode
(), J = null, x = null; DNode
Head = this; x = head. deleteAfter (head); for (; x! = Head; x = head. deleteAfter (head) {/* <= causes unstable sorting. Search if the advantage of insertion sorting cannot be reflected in the past and the future */j = list. prev; while (j! = List & x. val. compareTo (j. val) <0) {j = j. prev;/* if it is an array, shift arr [j + 1] = arr [j] Here. * It can be seen that the linked list is faster only when sizeof (T) is longer than the computer's word length */} System. out. println (list. toString () + "<--" + x. val + "at" + j. val); list. insertAfter (j, x);} return list;} public int search (T val) {/* If no-1 */DNode is found
First = this. next; int idx = 0; for (; first! = This; first = first. next) {if (0 = first. val. compareTo (val) return idx; ++ idx;} System. out. printf ("= xx \ n");/* why is this not played? A: Do not call println (search (I) like this; */return-1 ;}} public class implements listtest {public static void main (String [] arg) {/* Create a linked list header, and the node references */DNode
Head = new DNode
(), Node = null, curr = null; int I; for (I = 0; I <5; ++ I) {node = new DNode
(2 * I); head. insertTail (node);} System. out. println (head. toString (); for (I = 0; I <5; ++ I) {node = new DNode
(2 * I + 1); head. insertAfter (head, node);} System. out. println (head. toString (); I = 5; node = head. indexOf (I); head. deleteAfter (node); System. out. printf ("delete afert % d-th % d: \ n", I, node. val); System. out. println (head. toString (); head. reverseList (); System. out. println ("reversed: \ n" + head. toString (); node = head. insertionSort (); head = null; head = node;/* prevents Memory leakage. Will the compiler automatically implement it? */System. out. println ("Sorted: \ n" + head. toString (); I = 6; System. out. printf ("Search % d at pos % d \ n", I, head. search (I); head. deleteAll (); System. out. println ("deleteAll: \ n" + head. toString (); head = null ;}/ * ludi @ ubun :~ /Java $ javac-encoding UTF-8 into listtest. java & java example listtest [0, 2, 4, 6, 8,] [9, 7, 5, 3, 1, 0, 2, 4, 6, 8,] delete afert 5-th 0: [9, 7, 5, 3, 1, 0, 4, 6, 8,] reversed: [8, 6, 4, 0, 1, 3, 5, 7, 9,] Sorted: [0, 1, 3, 4, 5, 6, 7, 8, 9,] Search 6 at pos 5 deleteAll: [] ludi @ ubun :~ /Java $ */