数据结构学习java(一点五)链式顺序表(链表)
Posted dark_Souls
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构学习java(一点五)链式顺序表(链表)相关的知识,希望对你有一定的参考价值。
java中没有将指针暴露给用户(以前做过看过一篇文章写有java中是有指针的,只是被藏起来了),所以得使用引用的方式。
何为引用请看下面这篇文章(写的很不错,当然肯定比我写的好):
https://www.cnblogs.com/huajiezh/p/5835618.html
链表中内部类和嵌套类的区别:
https://blog.csdn.net/WelcomeSpring/article/details/79430546
以下代码采用内部类。
1 /** 2 * 内部类 3 * @param <E> 泛型 4 */ 5 private class Node<E>{ 6 E data; 7 Node<E> next; 8 Node<E> pre; 9 public Node(E data){ 10 this.data=data; 11 } 12 13 public Node(E data, Node next, Node pre) { 14 this.data = data; 15 this.next = next; 16 this.pre = pre; 17 } 18 public Node(){ 19 next=null; 20 pre=null; 21 data=null; 22 } 23 public E getData() { 24 return data; 25 } 26 27 public void setData(E data) { 28 this.data = data; 29 } 30 31 public Node getNext() { 32 return next; 33 } 34 35 public void setNext(Node next) { 36 this.next = next; 37 } 38 39 public Node getPre() { 40 return pre; 41 } 42 43 public void setPre(Node pre) { 44 this.pre = pre; 45 } 46 }
E data:存储对象的区域 Node<E> next:引用链表的下一个对象 Node<E> pre;引用链表的上一个对象 所构成了一个双链表
源代码:
1 /** 2 * @author 李正阳 3 * @param <E> 泛型 4 */ 5 public class MyLinkedList<E> implements List<E> { 6 7 private Node<E> head=new Node<>(); 8 private int size=0; 9 10 /** 11 * 在链表的最后插入元素 12 * @param data 插入的元素 13 * @return true 插入成功 14 */ 15 @Override 16 public boolean add(E data) { 17 Node<E> pNode= head; 18 while (pNode.getNext()!=null){ 19 pNode=pNode.next; 20 } 21 Node<E> temp=new Node(data); 22 temp.setPre(pNode); 23 pNode.setNext(temp); 24 size++; 25 return true; 26 } 27 28 /** 29 *在number位置添加一个元素 30 * @param number 在链表中的位置(不是从0开始) 31 * @return true 添加成功 32 */ 33 @Override 34 public boolean add(int number,E data){ 35 Node<E> pNode=head; 36 Node<E> temp=new Node<>(data); 37 for (int i=0;i<number;i++){ 38 pNode= pNode.getNext(); 39 } 40 pNode.getPre().setNext(temp); 41 temp.setPre(pNode.getPre()); 42 temp.setNext(pNode.getNext()); 43 pNode.getNext().setPre(temp); 44 return true; 45 } 46 /** 47 * 判空函数 48 * @return true 链表为空 false 链表不为空 49 */ 50 @Override 51 public boolean isEmpty() { 52 if(head.getNext()==null){ 53 return true; 54 }else { 55 return false; 56 } 57 } 58 59 /** 60 * 删除链表中number位置的元素 61 * @param number 元素在链表中的位置 62 * @return 删除的那个元素 63 */ 64 @Override 65 public E remove(int number) { 66 E temp; 67 Node<E> pNode,preNode; 68 pNode=head; 69 for(int i=0;i<number;i++){ 70 pNode=pNode.next; 71 } 72 temp=(E) pNode.getData(); 73 preNode=pNode.getPre(); 74 preNode.setNext(pNode.getNext()); 75 pNode.getNext().setPre(preNode); 76 pNode.setNext(null); 77 pNode.setPre(null); 78 pNode=null; 79 return temp; 80 } 81 82 /** 83 * 尾删法 84 * @return 删除的那个元素 85 */ 86 @Override 87 public E remove() { 88 E temp; 89 Node<E> pNode,preNode; 90 pNode=head; 91 while (pNode.getNext()!=null){ 92 pNode=pNode.next; 93 } 94 temp=(E) pNode.getData(); 95 preNode=pNode.getPre(); 96 preNode.setNext(null); 97 pNode.setNext(null); 98 pNode.setPre(null); 99 pNode=null; 100 return temp; 101 } 102 103 /** 104 * 将第i位置的元素替换 105 * @param i 元素在链表中的位置 106 * @param data 替换的元素 107 */ 108 @Override 109 public void set(int i, E data) { 110 Node<E> pNode=head; 111 for (int j=0;j<i;j++){ 112 pNode=pNode.getNext(); 113 } 114 pNode.setData(data); 115 } 116 117 /** 118 * 获得链表在i位置的元素 119 * @param i 元素在i位置的元素 120 * @return i位置的元素 121 */ 122 @Override 123 public E get(int i) { 124 E temp; 125 Node<E> pNode=head; 126 for (int j=0;j<i;j++){ 127 pNode=pNode.getNext(); 128 } 129 temp=(E) pNode.getData(); 130 return temp; 131 } 132 133 /** 134 * 检查这条链表现有的是否为回文 135 * @return true 为回文 false 不为回文 136 */ 137 @Override 138 public boolean isPalindrome() { 139 Node<E> pNode,nNode; 140 pNode=head.getNext(); 141 nNode=head; 142 while (nNode.getNext()!=null){ 143 nNode=nNode.getNext(); 144 } 145 StringBuilder posSequence=new StringBuilder(); 146 StringBuilder revOrder=new StringBuilder(); 147 while(pNode.getNext()!=null) { 148 posSequence.append(pNode.getData()); 149 pNode=pNode.getNext(); 150 } 151 posSequence.append(pNode.getData()); 152 while (nNode.getPre()!=null){ 153 revOrder.append(nNode.getData()); 154 nNode=nNode.getPre(); 155 } 156 String posequence=posSequence.toString(); 157 String revoredr=revOrder.toString(); 158 if(posequence.equals(revoredr)) { 159 return true; 160 }else { 161 return false; 162 } 163 } 164 165 /** 166 * 倒置链表 167 */ 168 @Override 169 public void reverseList(){ 170 Node<E> node,nNode; 171 node=head.getNext(); 172 node.setPre(node.getNext()); 173 node=node.getNext(); 174 nNode=node.getNext(); 175 head.getNext().setNext(null); 176 while (nNode!=null) { 177 node.setNext(node.getPre()); 178 node.setPre(nNode); 179 node=node.getPre(); 180 nNode=node.getNext(); 181 } 182 node.setNext(node.getPre()); 183 node.setPre(head); 184 head.setNext(node); 185 } 186 /** 187 * 头插法 188 * @param data 插入的元素 189 * @return true 添加成功 false 添加失败 190 */ 191 @Override 192 public boolean addFirst(E data){ 193 Node<E> node=new Node(data); 194 Node<E> preNode=head.getNext(); 195 head.setNext(node); 196 preNode.setPre(node); 197 node.setNext(preNode); 198 node.setPre(head); 199 return true; 200 } 201 202 /** 203 * 遍历并输出链表中的元素 204 */ 205 @Override 206 public void traver() { 207 if(isEmpty()){ 208 System.out.println("链表为空"); 209 }else { 210 Node<E> pNode = head.getNext(); 211 while (pNode != null) { 212 System.out.print(pNode.getData() + " "); 213 pNode = pNode.getNext(); 214 } 215 } 216 } 217 218 /** 219 * 内部类 220 * @param <E> 泛型 221 */ 222 private class Node<E>{ 223 E data; 224 Node<E> next; 225 Node<E> pre; 226 public Node(E data){ 227 this.data=data; 228 } 229 230 public Node(E data, Node next, Node pre) { 231 this.data = data; 232 this.next = next; 233 this.pre = pre; 234 } 235 public Node(){ 236 next=null; 237 pre=null; 238 data=null; 239 } 240 public E getData() { 241 return data; 242 } 243 244 public void setData(E data) { 245 this.data = data; 246 } 247 248 public Node getNext() { 249 return next; 250 } 251 252 public void setNext(Node next) { 253 this.next = next; 254 } 255 256 public Node getPre() { 257 return pre; 258 } 259 260 public void setPre(Node pre) { 261 this.pre = pre; 262 } 263 } 264 265 }
检查链表所存储是否为回文:
1 /** 2 * 检查这条链表现有的是否为回文 3 * @return true 为回文 false 不为回文 4 */ 5 @Override 6 public boolean isPalindrome() { 7 Node<E> pNode,nNode; 8 pNode=head.getNext(); 9 nNode=head; 10 while (nNode.getNext()!=null){ 11 nNode=nNode.getNext(); 12 } 13 StringBuilder posSequence=new StringBuilder(); 14 StringBuilder revOrder=new StringBuilder(); 15 while(pNode.getNext()!=null) { 16 posSequence.append(pNode.getData()); 17 pNode=pNode.getNext(); 18 } 19 posSequence.append(pNode.getData()); 20 while (nNode.getPre()!=null){ 21 revOrder.append(nNode.getData()); 22 nNode=nNode.getPre(); 23 } 24 String posequence=posSequence.toString(); 25 String revoredr=revOrder.toString(); 26 if(posequence.equals(revoredr)) { 27 return true; 28 }else { 29 return false; 30 } 31 }
* 算法设计:比较粗暴,直接从链表头到尾将值组成一个String
* 从链表尾到头将值组成一个String
* 然后比较这两个字符串是否相等
链表倒置:
1 /** 2 * 倒置链表 3 * 算法设计 4 */ 5 @Override 6 public void reverseList(){ 7 Node<E> node,nNode; 8 node=head.getNext(); 9 node.setPre(node.getNext()); 10 node=node.getNext(); 11 nNode=node.getNext(); 12 head.getNext().setNext(null); 13 while (nNode!=null) { 14 node.setNext(node.getPre()); 15 node.setPre(nNode); 16 node=node.getPre(); 17 nNode=node.getNext(); 18 } 19 node.setNext(node.getPre()); 20 node.setPre(head); 21 head.setNext(node); 22 }
* 算法设计:倒置链表需要修改三处地方,
* 头结点变成尾节点:将pre赋值尾next的引用,next赋值为null
* 尾节点变成头结点:将next赋值为pre,pre赋值为null
* 中间节点将next设置为pre,next设置为pre
以上是关于数据结构学习java(一点五)链式顺序表(链表)的主要内容,如果未能解决你的问题,请参考以下文章