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 }