双向链表
链表是是一种重要的数据结构,有单链表和双向链表之分;本文我将重点阐述不带头结点的双向链表:
不带头结点的带链表
我将对双链表的增加和删除元素操作进行如下解析
1.增加元素(采用尾插法)
(1)链表为空
新建结点,将头结点first和尾节点last都指向新建结点,尾节点的next指向空。
空链表增加元素
(2)链表非空
先定义一个临时的结点temp保存当前的尾节点,将尾节点last指向新建结点,并将last的prev指向temp,temp的next指向last.
非空链表增加元素
2.删除指定下标的元素
我将分以下三种情况进行讨论
(1)要删除元素为头结点
用node保存当前头结点first,并将头结点first指向first.next且将现在的first.prev置为空,将node.的next、data分别置为空。
删除头结点
(2)要删除元素为尾节点
用节点node保存当前的尾节点,将last指向当前尾节点的前一个节点last.prev,并将现last.next置为空,将以前的last即node节点的prev和data置空。
删除尾结点
(3)要删除元素为中间节点
用节点node保存要删除的节点,并将要删除节点的前一个节点的next指向要删除节点的下一个节点;要删除节点的下一个节点的prev指向要删除节点的还是那个一个节点;即node.prev. next = node.next;node.next.prev = node.prev。并将要删除节点的prev、next及data置为null.
删除中间结点
1 package Struct; 2 3 interface Link{ 4 void add(Object obj); 5 boolean remove(int index); 6 boolean contain(Object obj); 7 int indexOf(Object obj); 8 boolean set(int index,Object obj); 9 Object get(int index); 10 int length(); 11 void clear(); 12 Object[] toArray(); 13 void printArray(Object[] obj); 14 void printLink(); 15 } 16 class Factory{ 17 private Factory(){} 18 public static Link getLinkInstance(){ 19 return new LinkImpl(); 20 } 21 } 22 class LinkImpl implements Link{ 23 private Node first; 24 private Node last; 25 private int size; 26 private class Node{ 27 private Node prev; 28 private Node next; 29 private Object data; 30 public Node(Object data){ 31 this.data = data; 32 } 33 } 34 public void add(Object obj) { 35 //要插入元素为空 36 if(obj == null){ 37 return; 38 } 39 Node node = new Node(obj); 40 //空链表 41 if(first == null){ 42 first = last = node; 43 first.next = null; 44 size++; 45 }else{ 46 //非空链表(尾插) 47 Node temp = this.last; 48 temp.next = node; 49 last = node; 50 last.prev = temp; 51 size++; 52 } 53 } 54 //删除 55 public boolean remove(int index) { 56 //指定下标不合法 57 if(index >= size){ 58 return false; 59 } 60 Node node = first; 61 //要删除的节点为头结点 62 if(index == 0){ 63 first = node.next; 64 first.prev = null; 65 node.prev = node.next = null; 66 node.data = null; 67 size--; 68 return true; 69 } 70 //要删除节点为尾节点 71 if(index == size-1){ 72 Node node1 = last; 73 last = node1.prev; 74 last.next = null; 75 node1.prev = node1.next = null; 76 node1.data = null; 77 size--; 78 return true; 79 } 80 //要删除节点为中间节点 81 Node node3 = get(index); 82 node3.prev.next = node3.next; 83 node3.next.prev = node3.prev; 84 node3.prev = node3.next = null; 85 node3.data = null; 86 size--; 87 return true; 88 } 89 //查看元素是否包含在链表中 90 public boolean contain(Object obj) { 91 //空链表 92 if(first == null&&first.next==null){ 93 return false; 94 } 95 for(Node node = first;node!=null;node=node.next){ 96 if(node.data==obj){ 97 return true; 98 } 99 } 100 return false; 101 } 102 //求取元素obj的下标 103 public int indexOf(Object obj) { 104 Node node = first; 105 int signal = 0; 106 //空链表 107 if(first== null&& first.next == null){ 108 return -1; 109 }else{ 110 for(node = first;node!=null;node=node.next){ 111 if(node.data == obj){ 112 return signal; 113 } 114 signal++; 115 } 116 } 117 return signal; 118 } 119 //修改index处的值为obj 120 public boolean set(int index, Object obj) { 121 //指定位置不存在 122 if(index<0||index >= size){ 123 return false; 124 } 125 //指定下标超过链表长度 126 if(index >= size){ 127 return false; 128 } 129 Node node = first; 130 //若链表头结点是要修改的元素 131 if(node == get(index)){ 132 node.data = obj; 133 } 134 Object getObject = get(index); 135 for(node = first;node !=null;node=node.next){ 136 if( getObject == node){ 137 node.data = obj; 138 } 139 } 140 return true; 141 } 142 //取得index处的元素 143 public Node get(int index) { 144 if(first==null&&first.next==null){ 145 return null; 146 } 147 //要查找下标不在范围内 148 if(index >= size){ 149 return null; 150 } 151 Node node = first; 152 //要查找元素在中间元素的左侧 153 if(index >=0 && index <= (index<<1)){ 154 for(int i = 0;i <= index - 1;i++){ 155 if(i == index){ 156 return node; 157 } 158 node =node.next; 159 } 160 } 161 else if(index > (index<<1)){ 162 //要查找元素在中间元素的右侧 163 for(int i = index; i < size-1;i++){ 164 if(i == index){ 165 return node; 166 } 167 node = node.next; 168 } 169 } 170 return node; 171 } 172 //求链表长度 173 public int length() { 174 //空链表 175 if(first == null){ 176 return 0; 177 } 178 return this.size; 179 } 180 //清空链表 181 public void clear() { 182 183 Node node = first; 184 if(first == null && first.next == null){ 185 return; 186 } 187 for(node = first.next;node!=null;){ 188 Node temp = node; 189 node.prev = node.next = null; 190 node.data = null; 191 node = node.next; 192 size--; 193 } 194 first.next = null; 195 first.data = null; 196 size--; 197 } 198 //将链表转换成Object数组 199 public Object[] toArray() { 200 //空链表 201 if(first == null && first.next == null){ 202 return null; 203 }else{ 204 Object[] linkObject = new Object[this.size];//向上转型 205 Node node = first; 206 for(int i = 0;i<size;i++){ 207 linkObject[i] = node.data; 208 node = node.next; 209 } 210 return linkObject; 211 } 212 } 213 //打印Object数组 214 public void printArray(Object[] obj){ 215 for(int i = 0;i < obj.length;i++){ 216 System.out.print(obj[i]+" <-> "); 217 } 218 } 219 //打印链表 220 public void printLink() { 221 Node node = first; 222 for(node = first;node!=null;node=node.next){ 223 System.out.print(node.data+" <——> "); 224 } 225 System.out.println(); 226 } 227 228 } 229 public class DoubleLinkList { 230 public static void main(String[] args) { 231 Link link = Factory.getLinkInstance(); 232 System.out.println("\n"+"=================以下为add测试函数==================="); 233 link.add("我是开始位置"); 234 link.add("第一名"); 235 link.add("第二名"); 236 link.add("第三名"); 237 link.add("我是结束位置"); 238 System.out.println("\n"+"===============以下为printLink测试函数==============="); 239 link.printLink(); 240 System.out.println("\n"+"===============以下为indexOf测试函数================"); 241 System.out.println(link.indexOf("第二名")); 242 System.out.println(link.indexOf("我是结束位置")); 243 System.out.println("\n"+"===============以下为contain测试函数================"); 244 System.out.println(link.contain("我是结束位置")); 245 System.out.println(link.contain("hahh")); 246 System.out.println("\n"+"===============以下为get测试函数================"); 247 System.out.println(link.get(0)); 248 System.out.println(link.get(4)); 249 System.out.println(link.get(2)); 250 System.out.println(link.get(8)); 251 System.out.println("\n"+"===============以下为length测试函数================"); 252 System.out.println(link.length()); 253 System.out.println("\n"+"===============以下为set测试函数==================="); 254 System.out.println(link.set(0, "我是特等奖")); 255 link.printLink(); 256 System.out.println("\n"+"===============以下为toArray测试函数==================="); 257 Object[] linkObj = link.toArray(); 258 System.out.println("\n"+"===============以下为printArray测试函数==================="); 259 link.printArray(linkObj); 260 System.out.println("\n"+"===============以下为remove测试函数==================="); 261 //删除尾节点 262 System.out.println(link.remove(4)); 263 link.printLink(); 264 //删除头结点 265 System.out.println(link.remove(0)); 266 link.printLink(); 267 //删除中间节点 268 System.out.println(link.remove(1)); 269 link.printLink(); 270 System.out.println(link.length()); 271 System.out.println("\n"+"===============以下为clear测试函数==================="); 272 link.clear(); 273 System.out.println(link.length()); 274 } 275 }
测试结果: