一.雙向鏈式存儲: node
①簡述:要是節點中包含兩個指針部分,一個指向前驅元,一個指向後繼元,Java中LinkedList集合類的實現就是雙向鏈表網絡
(如下圖片爲網絡收集,侵刪)this
②特色:數據是非連續的,鏈表的運輸必須從頭指針開始;spa
③單鏈表相關操做:指針
A.插入操做code
B.刪除操做blog
④代碼實現: 索引
1 public class DoubleLinkedList<T> { 2 3 private int size;//鏈表大小 4 //因爲是雙向,頭尾任意選擇一端便可 5 private Node<T> head;//鏈表的頭節點 6 private Node<T> tail;//鏈表的尾節點 7 8 /** 9 * 內部類:節點 10 * @param <T> 11 */ 12 public static class Node<T>{ 13 private Node prev; 14 private Node next; 15 private T data; 16 17 public Node(T data){ 18 this.data = data; 19 } 20 21 private Node(){} 22 } 23 24 /** 25 * 添加到鏈尾 26 * @param data 27 */ 28 public void add(T data){ 29 add(size, data); 30 } 31 32 /** 33 * 添加到任意index處 34 * @param index 35 * @param data 36 */ 37 public void add(int index, T data){ 38 Node<T> node = new Node<>(data); 39 if(isEmpty()){//鏈表爲空 40 head = node; 41 tail = node; 42 }else { 43 if(index > size - 1){//索引超出當前鏈表大小,則添加到鏈尾 44 Node<T> temp = tail; 45 tail = node; 46 temp.next = tail; 47 tail.prev = temp; 48 }else {//原index位置處有值,索引位置大於index的元素向鏈尾移動(實際並非移動,只是看上去) 49 Node<T> origin = getNode(index); 50 Node<T> prev = origin.prev; 51 prev.next = node; 52 node.prev = prev; 53 node.next = origin; 54 origin.prev = node; 55 } 56 } 57 58 size++; 59 } 60 61 /** 62 * 更新index位置處元素的值 63 * @param index 64 * @param data 65 */ 66 public void set(int index, T data){ 67 if(index > size - 1 || index < 0){ 68 throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); 69 } 70 getNode(index).data = data; 71 } 72 73 /** 74 * 刪除index位置處的元素 75 * @param index 76 */ 77 public void delete(int index){ 78 if(index > size - 1 || index < 0){ 79 throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); 80 } 81 if(index == 0){//刪除鏈頭 82 head = head.next; 83 head.prev = null; 84 }else if(index == size -1){//刪除鏈尾 85 tail = tail.prev; 86 tail.next = null; 87 }else {//普通節點 88 Node<T> node = getNode(index); 89 Node prev = node.prev; 90 Node next = node.next; 91 prev.next = next; 92 next.prev = prev; 93 node.prev = null; 94 node.next = null; 95 } 96 size--; 97 } 98 99 /** 100 * 獲取index位置處的元素的值 101 * @param index 102 * @return 103 */ 104 public T getValue(int index){ 105 return getNode(index) == null ? null : getNode(index).data; 106 } 107 108 public T getValue(Node<T> node){ 109 return node == null ? null : node.data; 110 } 111 112 /** 113 * 獲取節點node的上一個節點 114 * @param node 115 * @return 116 */ 117 public Node<T> getPrevNode(Node<T> node){ 118 return node == null ? null : node.prev; 119 } 120 121 /** 122 * 獲取節點node的下一個節點 123 * @param node 124 * @return 125 */ 126 public Node<T> getNextNode(Node<T> node){ 127 return node == null ? null : node.next; 128 } 129 130 public Node<T> getHeadNode(){ 131 return head; 132 } 133 134 public Node<T> getTailNode(){ 135 return tail; 136 } 137 138 /** 139 * 獲取index位置處的元素 140 * @param index 141 * @return 142 */ 143 public Node<T> getNode(int index){ 144 145 if (isEmpty() && (index > size - 1)) { 146 throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); 147 } 148 Node<T> result = head; 149 int n = 0; 150 while (n < index) {//注意這裏是 n < index, 而不是n <= index 151 result = result.next; 152 n++; 153 } 154 return result; 155 } 156 157 /** 158 * 獲取值爲data的元素在鏈表中的位置(第一次出現的位置,可能含有多個) 159 * @param data 160 * @return 161 */ 162 public int indexOf(T data){ 163 if(isEmpty() || data == null){ 164 return -1; 165 } 166 167 int n = 0; 168 Node<T> node = head; 169 while (n < size){ 170 if(data.equals(node.data)){ 171 return n; 172 } 173 n++; 174 } 175 176 return -1; 177 } 178 179 /** 180 * 判斷是否有值爲data的元素 181 * @param data 182 * @return 183 */ 184 public boolean containValue(T data){ 185 return indexOf(data) != -1; 186 } 187 188 /** 189 * 獲取鏈表的大小 190 * @return 191 */ 192 public int size(){ 193 return size; 194 } 195 196 /** 197 * 判斷鏈表是否爲空 198 * @return 199 */ 200 public boolean isEmpty(){ 201 return size == 0; 202 } 203 204 205 }