链表的本质是一个动态数组。

链表的基本定义

在实际开发中对象数组非常实用,但是传统的对象数组长度是固定的,正因为如此,传统的数组应用非常有限。如果要想进行灵活的数据保存,需要自己来实现结构。
传统的对象数组采用索引控制,如果要想实现内容的动态维护难度太高。对于随时可能变化的数据使用不合理。
所谓链表的实质性本质是利用引用的逻辑关系来实现类似数组的数据处理操作,实现与数组类似的功能。

链表全部代码

  1. package com.Link;
  2. interface Link<E>{
  3. void add(E e);
  4. void show();
  5. int getSize();
  6. boolean isEmpty();
  7. Object[] toArray();
  8. E get(int index);//获取指定索引数据
  9. void set(int index,E data);
  10. boolean contains(E data);
  11. void remove(E data);
  12. void clean();
  13. }
  14. class LinkImpl<E> implements Link<E>{
  15. private class Node{
  16. private E data;
  17. private Node next;
  18. public Node(E e) {
  19. this.data = e;
  20. }
  21. void addNode(Node newNode) {
  22. if(this.next == null) {
  23. this.next = newNode;
  24. }
  25. else {
  26. this.next.addNode(newNode);
  27. }
  28. }
  29. void showNode() {
  30. System.out.println(this.data);
  31. }
  32. public void toArrayNode() {
  33. LinkImpl.this.returnData[LinkImpl.this.foot++] = this.data;
  34. if(this.next!=null) {
  35. this.next.toArrayNode();
  36. }
  37. }
  38. E getNode(int index) {
  39. if(LinkImpl.this.foot ++ == index) {//索引相同
  40. return this.data;
  41. }
  42. else {
  43. return this.next.getNode(index);
  44. }
  45. }
  46. void setNode(int index,E data) {
  47. if(LinkImpl.this.foot ++ == index) {//索引相同
  48. this.data = data;
  49. }
  50. else {
  51. this.next.setNode(index,data);
  52. }
  53. }
  54. boolean containsNode(E data) {
  55. if(this.data.equals(data)) {
  56. return true;
  57. }else {
  58. if(this.next == null) {
  59. return false;
  60. }
  61. else {
  62. return this.next.containsNode(data);
  63. }
  64. }
  65. }
  66. void removeNode(Node previous,E data) {//previous是上一个节点
  67. if(this.data.equals(data)) {
  68. previous.next = this.next;
  69. }else {
  70. if(this.next != null) {
  71. this.next.removeNode(this, data);
  72. }
  73. }
  74. }
  75. }
  76. private Node root = null;
  77. private int count = 0;
  78. private int foot = 0;
  79. private Object[] returnData;
  80. @Override
  81. public void add(E e) {
  82. // TODO Auto-generated method stub
  83. if(e == null) {
  84. return;
  85. }
  86. else {
  87. Node newNode = new Node(e);
  88. if(this.root == null) {
  89. this.root = newNode;
  90. }
  91. else {
  92. root.addNode(newNode);
  93. }
  94. this.count++;
  95. }
  96. }
  97. @Override
  98. public void show() {
  99. // TODO Auto-generated method stub
  100. Node tmp = root;
  101. while(tmp != null) {
  102. tmp.showNode();
  103. tmp = tmp.next;
  104. }
  105. }
  106. @Override
  107. public int getSize() {
  108. // TODO Auto-generated method stub
  109. return this.count;
  110. }
  111. @Override
  112. public boolean isEmpty() {
  113. // TODO Auto-generated method stub
  114. return this.count == 0;
  115. // return this.root == null;
  116. }
  117. @Override
  118. public Object[] toArray() {
  119. // TODO Auto-generated method stub
  120. if(this.isEmpty()) {
  121. return null;
  122. }
  123. else {
  124. this.returnData = new Object[this.count];
  125. this.root.toArrayNode();
  126. return this.returnData;
  127. }
  128. }
  129. @Override
  130. public E get(int index) {
  131. // TODO Auto-generated method stub
  132. if(index >= count) {
  133. return null;
  134. }
  135. else {
  136. this.foot = 0;
  137. return this.root.getNode(index);
  138. }
  139. }
  140. @Override
  141. public void set(int index, E data) {
  142. // TODO Auto-generated method stub
  143. if(index >= count) {
  144. return;
  145. }
  146. else {
  147. this.foot = 0;
  148. this.root.setNode(index, data);
  149. }
  150. }
  151. @Override
  152. public boolean contains(E data) {
  153. // TODO Auto-generated method stub
  154. return this.root.containsNode(data);
  155. }
  156. @Override
  157. public void remove(E data) {
  158. // TODO Auto-generated method stub
  159. if(this.contains(data)) {
  160. if(this.root.data.equals(data)) {
  161. this.root = this.root.next;//根节点和根节点的下一个变为同一个对象。
  162. }
  163. else {
  164. this.root.next.removeNode(this.root, data);
  165. }
  166. count--;
  167. }
  168. }
  169. @Override
  170. public void clean() {
  171. // TODO Auto-generated method stub
  172. this.count = 0;
  173. this.root = null;
  174. }
  175. }
  176. public class Test {
  177. public static void main(String[] args) {
  178. LinkImpl<String> all = new LinkImpl<String>();
  179. System.out.println(all.isEmpty());
  180. all.add("111");
  181. all.add("222");
  182. all.add("333");
  183. all.show();
  184. System.out.println(all.getSize());
  185. System.out.println(all.isEmpty());
  186. Object res[] = all.toArray();
  187. for(Object obj:res) {
  188. System.out.println(obj.toString());
  189. }
  190. System.out.println(all.get(2));
  191. all.set(2, "444");
  192. System.out.println(all.get(2));
  193. System.out.println(all.contains("111"));
  194. System.out.println(all.contains("199"));
  195. all.remove("111");
  196. all.show();
  197. all.clean();
  198. all.show();
  199. }
  200. }