|
@@ -0,0 +1,103 @@
|
|
|
|
+package com.sf.javase;
|
|
|
|
+
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.LinkedList;
|
|
|
|
+
|
|
|
|
+public class LinkedListMain<E> {
|
|
|
|
+
|
|
|
|
+ public static void main(String[] args) {
|
|
|
|
+ ArrayList<String> list1 = new ArrayList<>();
|
|
|
|
+ list1.add("a");
|
|
|
|
+
|
|
|
|
+ LinkedList<String> list = new LinkedList<>();
|
|
|
|
+ list.add("a");
|
|
|
|
+ // 在指定位置插入元素
|
|
|
|
+ // 根据位置找到元素 再插入
|
|
|
|
+ list.add(0, "b");
|
|
|
|
+
|
|
|
|
+ LinkedListMain<String> myList = new LinkedListMain<>();
|
|
|
|
+ myList.add("a");
|
|
|
|
+ myList.add("b");
|
|
|
|
+ System.out.println(myList);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public boolean add(E e) {
|
|
|
|
+ // 在链表尾部插入元素
|
|
|
|
+ Node<E> l = last;
|
|
|
|
+ // 将要添加的元素 创建一个节点
|
|
|
|
+ Node<E> newNode = new Node<>(l, e, null);
|
|
|
|
+ // 将尾节点更新为新的节点
|
|
|
|
+ last = newNode;
|
|
|
|
+ // 验证是否是第一次添加元素
|
|
|
|
+ if (l == null) {
|
|
|
|
+ // 此时添加的元素也是头节点
|
|
|
|
+ head = newNode;
|
|
|
|
+ } else {
|
|
|
|
+ // 如果之前的尾结点不为空
|
|
|
|
+ l.next = newNode;
|
|
|
|
+ }
|
|
|
|
+ size++;
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void add(int index, E e) {
|
|
|
|
+ // 判断是否越界
|
|
|
|
+ // 判断是否是最后一个位置
|
|
|
|
+ if (index == size) {
|
|
|
|
+ add(e);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ // 找到当前元素
|
|
|
|
+ Node<E> curr = node(index);
|
|
|
|
+ // 可以放在当前元素之前 也可以放在之后 linkedlist源代码是放在之前
|
|
|
|
+ Node<E> prev = curr.prev;
|
|
|
|
+ // 构造节点 和前置后置的关系
|
|
|
|
+ Node<E> newNode = new Node<>(prev, e, curr);
|
|
|
|
+ curr.prev = newNode;
|
|
|
|
+ if (prev != null) prev.next = newNode;
|
|
|
|
+ // 如果prev为空 代表curr是头节点 插入新元素后 头节点变化
|
|
|
|
+ else head = newNode;
|
|
|
|
+ size++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 通过指定位置获取元素
|
|
|
|
+ public Node<E> node(int index) {
|
|
|
|
+ // 索引为0 对应头节点
|
|
|
|
+ // 优化 根据索引的位置 决定从前往后遍历 还是从后往前遍历
|
|
|
|
+ // 位运算 10<<100 乘2 100>>10 除2
|
|
|
|
+ if (index < (size >> 1)) {
|
|
|
|
+ // 从头节点往后遍历
|
|
|
|
+ Node<E> x = head;
|
|
|
|
+ for (int i = 0; i < index; i++) {
|
|
|
|
+ x = x.next;
|
|
|
|
+ }
|
|
|
|
+ return x;
|
|
|
|
+ } else {
|
|
|
|
+ // 从后往前遍历
|
|
|
|
+ Node<E> x = last;
|
|
|
|
+ for (int i = size - 1; i > index; i--) {
|
|
|
|
+ x = x.prev;
|
|
|
|
+ }
|
|
|
|
+ return x;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 头节点和尾节点
|
|
|
|
+ private Node<E> head;
|
|
|
|
+ private Node<E> last;
|
|
|
|
+ // 当前链表的长度
|
|
|
|
+ private int size;
|
|
|
|
+
|
|
|
|
+ // 双向链表节点的基本结构
|
|
|
|
+ private static class Node<E> {
|
|
|
|
+ E item;
|
|
|
|
+ Node<E> next;
|
|
|
|
+ Node<E> prev;
|
|
|
|
+
|
|
|
|
+ Node(Node<E> prev, E element, Node<E> next) {
|
|
|
|
+ this.item = element;
|
|
|
|
+ this.next = next;
|
|
|
|
+ this.prev = prev;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|