1. 单链表

  1. /**
  2. * @Author dyliang
  3. * @Date 2020/10/2 15:04
  4. * @Version 1.0
  5. */
  6. class ListNode{
  7. int value;
  8. ListNode next;
  9. public ListNode(int value) {
  10. this.value = value;
  11. }
  12. }
  13. public class SingleDirectionList {
  14. public static ListNode head = new ListNode(1);
  15. public static void main(String[] args) {
  16. ListNode cur = head;
  17. for (int i = 2; i < 5; i++) {
  18. cur.next = new ListNode(i);
  19. cur = cur.next;
  20. }
  21. printList(head);
  22. printList(insertToHead(head, 5));
  23. printList(insertToList(head, 2, 8));
  24. printList(removeNode(head, 2));
  25. }
  26. // 头部插入
  27. public static ListNode insertToHead(ListNode head, int value){
  28. ListNode node = new ListNode(value);
  29. node.next = head;
  30. head = node;
  31. return head;
  32. }
  33. // 指定索引处插入指定值的节点
  34. public static ListNode insertToList(ListNode head, int index, int value){
  35. if(index < 0 || index > lengthOfList(head)){
  36. return null;
  37. }
  38. ListNode cur = head;
  39. int l = 0;
  40. while (cur != null){
  41. if(l == index - 1){
  42. ListNode node = new ListNode(value);
  43. node.next = cur.next;
  44. cur.next = node;
  45. break;
  46. }else{
  47. cur = cur.next;
  48. l++;
  49. }
  50. }
  51. return head;
  52. }
  53. // 移除指定索引处节点
  54. public static ListNode removeNode(ListNode head, int index){
  55. ListNode cur = head;
  56. int l = 0;
  57. while (cur != null){
  58. if(l == index - 1){
  59. cur.next = cur.next.next;
  60. break;
  61. }else{
  62. cur = cur.next;
  63. l++;
  64. }
  65. }
  66. return head;
  67. }
  68. // 打印链表
  69. public static void printList(ListNode head){
  70. while(head != null){
  71. System.out.print(head.value + "->");
  72. head = head.next;
  73. }
  74. System.out.println();
  75. }
  76. // 链表长度
  77. public static int lengthOfList(ListNode head){
  78. int length = 0;
  79. while(head != null){
  80. length++;
  81. head = head.next;
  82. }
  83. return length;
  84. }
  85. }

2. 双向链表

  1. /**
  2. * @Author dyliang
  3. * @Date 2020/10/2 15:21
  4. * @Version 1.0
  5. */
  6. public class DoubleLinkedList<T> {
  7. private int size;//链表大小
  8. private Node<T> head;//链表的头节点
  9. private Node<T> tail;//链表的尾节点
  10. /**
  11. * 内部类:节点
  12. * @param <T>
  13. */
  14. public static class Node<T>{
  15. private Node prev;
  16. private Node next;
  17. private T data;
  18. public Node(T data){
  19. this.data = data;
  20. }
  21. private Node(){}
  22. }
  23. /**
  24. * 添加到链尾
  25. * @param data
  26. */
  27. public void add(T data){
  28. add(size, data);
  29. }
  30. /**
  31. * 添加到任意index处
  32. * @param index
  33. * @param data
  34. */
  35. public void add(int index, T data){
  36. Node<T> node = new Node<>(data);
  37. if(isEmpty()) {//链表为空
  38. head = node;
  39. tail = node;
  40. }
  41. if(index > size - 1){//索引超出当前链表大小,则添加到链尾
  42. Node<T> temp = tail;
  43. tail = node;
  44. temp.next = tail;
  45. tail.prev = temp;
  46. }else {//原index位置处有值,索引位置大于index的元素向链尾移动(实际并不是移动,只是看上去)
  47. Node<T> origin = getNode(index);
  48. Node<T> prev = origin.prev;
  49. prev.next = node;
  50. node.prev = prev;
  51. node.next = origin;
  52. origin.prev = node;
  53. }
  54. size++;
  55. }
  56. /**
  57. * 更新index位置处元素的值
  58. * @param index
  59. * @param data
  60. */
  61. public void set(int index, T data){
  62. if(index > size - 1 || index < 0){
  63. throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
  64. }
  65. getNode(index).data = data;
  66. }
  67. /**
  68. * 删除index位置处的元素
  69. * @param index
  70. */
  71. public void delete(int index){
  72. if(index > size - 1 || index < 0){
  73. throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
  74. }
  75. if(index == 0){//删除链头
  76. head = head.next;
  77. head.prev = null;
  78. }else if(index == size -1){//删除链尾
  79. tail = tail.prev;
  80. tail.next = null;
  81. }else {//普通节点
  82. Node<T> node = getNode(index);
  83. Node prev = node.prev;
  84. Node next = node.next;
  85. prev.next = next;
  86. next.prev = prev;
  87. node.prev = null;
  88. node.next = null;
  89. }
  90. size--;
  91. }
  92. /**
  93. * 获取index位置处的元素的值
  94. * @param index
  95. * @return
  96. */
  97. public T getValue(int index){
  98. return getNode(index) == null ? null : getNode(index).data;
  99. }
  100. public T getValue(Node<T> node){
  101. return node == null ? null : node.data;
  102. }
  103. /**
  104. * 获取节点node的上一个节点
  105. * @param node
  106. * @return
  107. */
  108. public Node<T> getPrevNode(Node<T> node){
  109. return node == null ? null : node.prev;
  110. }
  111. /**
  112. * 获取节点node的下一个节点
  113. * @param node
  114. * @return
  115. */
  116. public Node<T> getNextNode(Node<T> node){
  117. return node == null ? null : node.next;
  118. }
  119. public Node<T> getHeadNode(){
  120. return head;
  121. }
  122. public Node<T> getTailNode(){
  123. return tail;
  124. }
  125. /**
  126. * 获取index位置处的元素
  127. * @param index
  128. * @return
  129. */
  130. public Node<T> getNode(int index){
  131. if (isEmpty() && (index > size - 1)) {
  132. throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
  133. }
  134. Node<T> result = head;
  135. int n = 0;
  136. while (n < index) {//注意这里是 n < index, 而不是n <= index
  137. result = result.next;
  138. n++;
  139. }
  140. return result;
  141. }
  142. /**
  143. * 获取值为data的元素在链表中的位置(第一次出现的位置,可能含有多个)
  144. * @param data
  145. * @return
  146. */
  147. public int indexOf(T data){
  148. if(isEmpty() || data == null){
  149. return -1;
  150. }
  151. int n = 0;
  152. Node<T> node = head;
  153. while (n < size){
  154. if(data.equals(node.data)){
  155. return n;
  156. }
  157. n++;
  158. }
  159. return -1;
  160. }
  161. /**
  162. * 判断是否有值为data的元素
  163. * @param data
  164. * @return
  165. */
  166. public boolean containValue(T data){
  167. return indexOf(data) != -1;
  168. }
  169. /**
  170. * 获取链表的大小
  171. * @return
  172. */
  173. public int size(){
  174. return size;
  175. }
  176. /**
  177. * 判断链表是否为空
  178. * @return
  179. */
  180. public boolean isEmpty(){
  181. return size == 0;
  182. }
  183. }