1 public class ListNode {
2 public int val ;
3 public ListNode next;
4 public ListNode(int val) {
5 this.val = val;
6 this.next = null ;
7 }
8
9 }
1 public class MyLinkedList { 2 3 //hide from direct access. only expose the methods 4 public ListNode head ; 5 public ListNode tail ; 6 public int length; 7 8 public MyLinkedList() { 9 this.head = null ; 10 this.tail = null ; 11 this.length = 0 ; 12 } 13 //=== since the head and tail are encapsulated, very improtant dont loose the head=== 14 //1 15 public void appendHead(int value){ 16 ListNode node = new ListNode(value) ; 17 node.next = head ; 18 head = node ; 19 length++ ; 20 syncHeadAndTail(); 21 } 22 23 //2: 3->4->null 5 24 public void appendTail(int value){ 25 if (head==null){ 26 this.appendHead(value); 27 } else{ 28 tail.next = new ListNode(value) ; 29 tail = tail.next ; 30 length++ ; 31 } 32 } 33 34 //=== assume there is no duplicate values 35 //corner case: no matching value 36 //3: 3->4-> null 37 public void removeValue(int value){ 38 if (head == null) return ; 39 if (head.val == value){ 40 head = head.next ; //corner case: 3-> null removeValue 3 41 length--; 42 syncHeadAndTail(); 43 } 44 //1->3->null 3 45 else{ 46 ListNode curr = head ; 47 ListNode pre = null ; 48 while (curr != null ){ 49 pre = curr ; 50 curr = curr.next ; 51 if (curr.val == value){ 52 pre.next = curr.next ; 53 length--; 54 tail = pre ; 55 return; 56 } 57 } 58 } 59 } 60 61 //4: note here the length is length 62 public void removeIndex(int index){ 63 //index >= length also covers the head == null case 64 if (index < 0 || index >= length) return; 65 //if removeValue at the head: 66 if (index == 0){ 67 head = head.next ; 68 } else{ 69 ListNode curr = head ; 70 for (int i = 0; i < index -1 ; i++) { 71 curr = curr.next ; 72 } 73 //special case for tail 74 if (index == length - 1){ 75 tail = curr ; 76 } 77 curr.next = curr.next.next ; 78 } 79 length--; 80 syncHeadAndTail(); 81 //if removeValue at the end: update the tail 82 } 83 84 private void syncHeadAndTail(){ 85 if (length == 0){ 86 head = null ; 87 tail = null ; 88 } 89 if (length == 1){ 90 tail = head ; 91 } 92 } 93 94 //5: Integer get(int index): there would be chance return null. thats the reason we return wrapper 95 public Integer get(int index){ 96 if (index < 0 || index >= length) return null; 97 ListNode curr = head ; 98 //one step short 99 for (int i = 0; i < index; i++) { 100 curr = curr.next ; 101 } 102 return curr.val ; 103 } 104 //6: Integer set(int index, int value): update by index. return the previous value 105 public Integer set(int index, int value){ 106 if (index < 0 || index >= length) return null; 107 ListNode curr = head ; 108 //one step short 109 for (int i = 0; i < index; i++) { 110 curr = curr.next ; 111 } 112 int temp = curr.val ; 113 curr.val = value ; 114 return temp ; 115 } 116 //7: return the length: eager computation 117 public int size(){ 118 return this.length; 119 } 120 121 //8: 122 public boolean isEmpty(){ 123 return this.length <0; 124 } 125 //9: removeValue head 126 public void clear(){ 127 head = null ; 128 tail = null ; 129 } 130 //31524 131 public static void main(String[] args) { 132 MyLinkedList list = new MyLinkedList(); 133 list.appendHead(1); 134 list.appendHead(3); 135 list.appendTail(5); 136 list.appendTail(2); 137 list.appendTail(4); 138 ListNode curr = list.head ; 139 //3->1->5->2->4-> 140 while (curr !=null){ 141 System.out.print(curr.val + "->"); 142 curr = curr.next ; 143 } 144 System.out.println("head:" + list.head.val + " ; tail:" + list.tail.val); 145 System.out.println(list.get(2)); 146 System.out.println("is empty:" + list.isEmpty()); 147 list.removeIndex(2); 148 //list.removeValue(4); 149 list.removeIndex(list.size()-1); 150 System.out.println("head:" + list.head.val + " ; tail:" + list.tail.val); 151 list.removeValue(2); 152 //list.removeIndex(0); 153 curr = list.head ; 154 while (curr !=null){ 155 System.out.print(curr.val + "->"); 156 curr = curr.next ; 157 } 158 System.out.println("head:" + list.head.val + " ; tail:" + list.tail.val); 159 160 /* 161 the test result: 162 3->1->5->2->4->head:3 ; tail:4 163 5 164 is empty:false 165 head:3 ; tail:2 166 3->1-> head:3 ; tail:1 167 * */ 168 } 169 }