✊不积跬步,无以至千里;不积小流,无以成江海。
一、双向链表
public class DuLinkedList<T> implements Iterable<T> {// 记录头结点private Node head;// 记录最后一个结点private Node last;// 记录链表长度private int N;public DuLinkedList() {// 初始化头结点和尾结点last = null;head = new Node(null,null,null);// 初始化链表长度N = 0;}// 清空链表public void clear() {this.head.next = null;this.last = null;this.N = 0;}// 获取链表的长度public int length() {return N;}// 判断链表是否为空public boolean isEmpty() {return N == 0;}// 获取第一个元素public T getFirst() {if (isEmpty()) {return null;}return head.next.item;}// 获取最后一个元素public T getLast() {if (isEmpty()) {return null;}return last.item;}// 插入元素tpublic void insert(T t) {if (isEmpty()) {// 创建新结点Node newNode = new Node(t, head, null);// 新结点成为尾结点last = newNode;// 头结点指向尾结点head.next = last;} else {Node oldLast = last;Node newNode = new Node(t, oldLast, null);oldLast.next = newNode;last = newNode;}// 元素个数加1N++;}// 向指定位置i处插入元素tpublic void insert(T t, int i) {// 先找到第i个元素的前一个结点Node pre = head;for (int index=0; index<i; index++) {pre = pre.next;}// 找到第i个结点Node curr = pre.next;// 创建新结点Node newNode = new Node(t, pre, curr);// 第i个结点的上一个结点的下一个结点为新结点pre.next = newNode;// 第i个结点的上一个结点为新结点curr.pre = newNode;// 链表长度加1N++;}// 获取指定位置i处的元素public T get(int i) {Node curr = head;for (int index=0; index<i; index++) {curr = curr.next;}return curr.next.item;}// 找到元素t在链表中第一次出现的位置public int indexOf(T t) {Node curr = head;for (int i=0; curr.next != null; i++) {curr = curr.next;if (t.equals(curr.item)) {return i;}}return -1;}// 删除指定i位置元素,并返回该元素public T remove(int i) {// 先找到第i个结点的上一个结点Node pre = head;for (int index=0; index<i; index++) {pre = pre.next;}// 找到第i个结点Node curr = pre.next;// 第i个结点的上一个结点指向第i个结点的下一个结点pre.next = curr.next;// 第i个结点的下一个结点指向第i个结点的上一个结点curr.pre = pre;// 链表长度减1N--;return curr.item;}private class Node {public Node(T item, Node pre, Node next) {this.item = item;this.pre = pre;this.next = next;}// 存储数据public T item;// 上一个结点public Node pre;// 下一个结点public Node next;}/*** 遍历链表* @return*/@Overridepublic Iterator iterator() {return new MyIterator();}private class MyIterator implements Iterator {private Node n;public MyIterator(){this.n = head;}@Overridepublic boolean hasNext() {return n.next != null;}@Overridepublic Object next() {n = n.next;return n.item;}}// 反转链表public void reverse() {if (isEmpty()){return;}reverse(head.next);}// 递归反转链表,并返回当前节点public Node reverse(Node curr) {if (curr.next == null) {// 头结点指向最后一个结点head.next = curr;return curr;}// 递归反转当前节点的下一个结点,返回反转后下一个结点的前一个结点为当前节点Node pre = reverse(curr.next);pre.next = curr;// 将当前结点的下一个结点为nullcurr.next = null;return curr;}}
二、队列
package com.linjie.test.linear;import java.util.Iterator;/*** @Title:Queue* @Package:com.linjie.test.linear* @Description:* @author:done* @date:2021/11/24 19:47*/public class Queue<T> implements Iterable<T>{// 记录首结点private Node head;// 记录最后一个结点private Node last;// 当前栈的元素个数private int N;private class Node{public T item;public Node next;public Node(T item, Node next){this.item = item;this.next = next;}}// 队列public Queue(){this.head = new Node(null, null);this.N = 0;this.last = null;}// 判断队列是否为空public boolean isEmpty(){return N == 0;}// 返回队列的元素个数public int size(){return N;}// 向队列中插入元素tpublic void enqueue(T t){if (last == null){last = new Node(t, null);head.next = last;} else {Node oldNode = last;last = new Node(t, null);oldNode.next = last;}// 元素个数加1N++;}// 从队列中拿出一个元素public T dequeue(){if (isEmpty()){return null;}Node oldFirst = head.next;head.next = oldFirst.next;N--;// 出队列实际为删除元素,若队列为空,需重置if (isEmpty()){last = null;}return oldFirst.item;}@Overridepublic Iterator<T> iterator() {return new MyIterator();}private class MyIterator implements Iterator{private Node n;public MyIterator(){this.n = head;}@Overridepublic boolean hasNext() {return n.next != null;}@Overridepublic Object next() {n = n.next;return n.item;}}}
