✊不积跬步,无以至千里;不积小流,无以成江海。

一、双向链表

  1. public class DuLinkedList<T> implements Iterable<T> {
  2. // 记录头结点
  3. private Node head;
  4. // 记录最后一个结点
  5. private Node last;
  6. // 记录链表长度
  7. private int N;
  8. public DuLinkedList() {
  9. // 初始化头结点和尾结点
  10. last = null;
  11. head = new Node(null,null,null);
  12. // 初始化链表长度
  13. N = 0;
  14. }
  15. // 清空链表
  16. public void clear() {
  17. this.head.next = null;
  18. this.last = null;
  19. this.N = 0;
  20. }
  21. // 获取链表的长度
  22. public int length() {
  23. return N;
  24. }
  25. // 判断链表是否为空
  26. public boolean isEmpty() {
  27. return N == 0;
  28. }
  29. // 获取第一个元素
  30. public T getFirst() {
  31. if (isEmpty()) {
  32. return null;
  33. }
  34. return head.next.item;
  35. }
  36. // 获取最后一个元素
  37. public T getLast() {
  38. if (isEmpty()) {
  39. return null;
  40. }
  41. return last.item;
  42. }
  43. // 插入元素t
  44. public void insert(T t) {
  45. if (isEmpty()) {
  46. // 创建新结点
  47. Node newNode = new Node(t, head, null);
  48. // 新结点成为尾结点
  49. last = newNode;
  50. // 头结点指向尾结点
  51. head.next = last;
  52. } else {
  53. Node oldLast = last;
  54. Node newNode = new Node(t, oldLast, null);
  55. oldLast.next = newNode;
  56. last = newNode;
  57. }
  58. // 元素个数加1
  59. N++;
  60. }
  61. // 向指定位置i处插入元素t
  62. public void insert(T t, int i) {
  63. // 先找到第i个元素的前一个结点
  64. Node pre = head;
  65. for (int index=0; index<i; index++) {
  66. pre = pre.next;
  67. }
  68. // 找到第i个结点
  69. Node curr = pre.next;
  70. // 创建新结点
  71. Node newNode = new Node(t, pre, curr);
  72. // 第i个结点的上一个结点的下一个结点为新结点
  73. pre.next = newNode;
  74. // 第i个结点的上一个结点为新结点
  75. curr.pre = newNode;
  76. // 链表长度加1
  77. N++;
  78. }
  79. // 获取指定位置i处的元素
  80. public T get(int i) {
  81. Node curr = head;
  82. for (int index=0; index<i; index++) {
  83. curr = curr.next;
  84. }
  85. return curr.next.item;
  86. }
  87. // 找到元素t在链表中第一次出现的位置
  88. public int indexOf(T t) {
  89. Node curr = head;
  90. for (int i=0; curr.next != null; i++) {
  91. curr = curr.next;
  92. if (t.equals(curr.item)) {
  93. return i;
  94. }
  95. }
  96. return -1;
  97. }
  98. // 删除指定i位置元素,并返回该元素
  99. public T remove(int i) {
  100. // 先找到第i个结点的上一个结点
  101. Node pre = head;
  102. for (int index=0; index<i; index++) {
  103. pre = pre.next;
  104. }
  105. // 找到第i个结点
  106. Node curr = pre.next;
  107. // 第i个结点的上一个结点指向第i个结点的下一个结点
  108. pre.next = curr.next;
  109. // 第i个结点的下一个结点指向第i个结点的上一个结点
  110. curr.pre = pre;
  111. // 链表长度减1
  112. N--;
  113. return curr.item;
  114. }
  115. private class Node {
  116. public Node(T item, Node pre, Node next) {
  117. this.item = item;
  118. this.pre = pre;
  119. this.next = next;
  120. }
  121. // 存储数据
  122. public T item;
  123. // 上一个结点
  124. public Node pre;
  125. // 下一个结点
  126. public Node next;
  127. }
  128. /**
  129. * 遍历链表
  130. * @return
  131. */
  132. @Override
  133. public Iterator iterator() {
  134. return new MyIterator();
  135. }
  136. private class MyIterator implements Iterator {
  137. private Node n;
  138. public MyIterator(){
  139. this.n = head;
  140. }
  141. @Override
  142. public boolean hasNext() {
  143. return n.next != null;
  144. }
  145. @Override
  146. public Object next() {
  147. n = n.next;
  148. return n.item;
  149. }
  150. }
  151. // 反转链表
  152. public void reverse() {
  153. if (isEmpty()){
  154. return;
  155. }
  156. reverse(head.next);
  157. }
  158. // 递归反转链表,并返回当前节点
  159. public Node reverse(Node curr) {
  160. if (curr.next == null) {
  161. // 头结点指向最后一个结点
  162. head.next = curr;
  163. return curr;
  164. }
  165. // 递归反转当前节点的下一个结点,返回反转后下一个结点的前一个结点为当前节点
  166. Node pre = reverse(curr.next);
  167. pre.next = curr;
  168. // 将当前结点的下一个结点为null
  169. curr.next = null;
  170. return curr;
  171. }
  172. }

二、队列

  1. package com.linjie.test.linear;
  2. import java.util.Iterator;
  3. /**
  4. * @Title:Queue
  5. * @Package:com.linjie.test.linear
  6. * @Description:
  7. * @author:done
  8. * @date:2021/11/24 19:47
  9. */
  10. public class Queue<T> implements Iterable<T>{
  11. // 记录首结点
  12. private Node head;
  13. // 记录最后一个结点
  14. private Node last;
  15. // 当前栈的元素个数
  16. private int N;
  17. private class Node{
  18. public T item;
  19. public Node next;
  20. public Node(T item, Node next){
  21. this.item = item;
  22. this.next = next;
  23. }
  24. }
  25. // 队列
  26. public Queue(){
  27. this.head = new Node(null, null);
  28. this.N = 0;
  29. this.last = null;
  30. }
  31. // 判断队列是否为空
  32. public boolean isEmpty(){
  33. return N == 0;
  34. }
  35. // 返回队列的元素个数
  36. public int size(){
  37. return N;
  38. }
  39. // 向队列中插入元素t
  40. public void enqueue(T t){
  41. if (last == null){
  42. last = new Node(t, null);
  43. head.next = last;
  44. } else {
  45. Node oldNode = last;
  46. last = new Node(t, null);
  47. oldNode.next = last;
  48. }
  49. // 元素个数加1
  50. N++;
  51. }
  52. // 从队列中拿出一个元素
  53. public T dequeue(){
  54. if (isEmpty()){
  55. return null;
  56. }
  57. Node oldFirst = head.next;
  58. head.next = oldFirst.next;
  59. N--;
  60. // 出队列实际为删除元素,若队列为空,需重置
  61. if (isEmpty()){
  62. last = null;
  63. }
  64. return oldFirst.item;
  65. }
  66. @Override
  67. public Iterator<T> iterator() {
  68. return new MyIterator();
  69. }
  70. private class MyIterator implements Iterator{
  71. private Node n;
  72. public MyIterator(){
  73. this.n = head;
  74. }
  75. @Override
  76. public boolean hasNext() {
  77. return n.next != null;
  78. }
  79. @Override
  80. public Object next() {
  81. n = n.next;
  82. return n.item;
  83. }
  84. }
  85. }