主體
public class LinkWithHead<T> {
private Node<T> head;
private int size;
private class Node<T> {
public Node<T> next;
public T data;
public Node(T data, Node<T> next) {
this.next = next;
this.data = data;
}
}
public LinkWithHead() {
this.head = new Node<T>(null, null);
this.size = 0;
}
}
複製程式碼
判斷連結串列是否為空
private boolean isEmpty() {
return head.next == null;
}
複製程式碼
新增一個結點
private void insert(Node<T> node) {
Node<T> temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = node;
size++;
}
複製程式碼
在指定位置新增一個結點
private void insert(Node<T> node, int index) {
if (index > size + 1 || size < 0) {
throw new ArrayIndexOutOfBoundsException();
}
if (head == null && index == 0)
head.next = node;
else {
int currentIndex = 0;
Node<T> temp = head;
while (currentIndex < index) {
temp = temp.next;
currentIndex++;
}
node.next = temp.next;
temp.next = node;
size++;
}
}
複製程式碼
刪除一個結點(迴圈法)
private void remove(Node<T> node) {
if (head == node) {
head = null;
size = 0;
} else {
Node<T> temp = head;
while (temp.next != node) {
temp = temp.next;
}
temp.next = temp.next.next;
size--;
}
}
複製程式碼
刪除指定位置的結點
private void removeByIndex(int index) {
if (index < 1 || index > size - 1) {
throw new ArrayIndexOutOfBoundsException();
}
int current = 0;
Node<T> temp = head;
while (current < index) {
temp = temp.next;
current++;
}
temp.next = temp.next.next;
}
複製程式碼
刪除結點時間複雜度O(1)
private void remove2(Node<T> node) {
if (head == node) {
head = null;
size = 0;
} else {
Node<T> temp = node.next;
node.data = temp.data;
node.next = temp.next;
size--;
}
}
複製程式碼
用棧的方式刪除指定位置結點
private void removeByStack(int index) {
Stack<Node<T>> stack = new Stack<>();
stack.push(head);
int current = 0;
while (head != null) {
head = head.next;
current++;
if (current != index)
stack.push(head);
}
while (!stack.isEmpty()) {
stack.peek().next = head;
head = stack.pop();
}
}
複製程式碼
刪除連結串列中的重複資料
private void removeDuplication() {
HashSet<T> set = new HashSet<>();
Node<T> previous = head;
Node<T> current = head.next;
set.add(head.data);
while (current != null) {
if (!set.contains(previous.data)) {
set.add(previous.data);
previous = current;
current = current.next;
} else {
previous.next = current.next;
current = current.next;
}
}
}
複製程式碼
刪除連結串列中倒數第K個結點
private void removeLastKthNode(int k) {
if (k < 0 || k > size)
throw new ArrayIndexOutOfBoundsException();
Node<T> temp = head;
for (int i = 0; i < k; i++) {
temp = temp.next;
}
Node<T> previous = head;
while (temp.next != null) {
temp = temp.next;
previous = previous.next;
}
previous.next = previous.next.next;
}
複製程式碼
反轉連結串列
private Node<T> reverse(Node<T> node) {
if (node == null || node.next == null)
return node;
Node<T> previous = reverse(node.next);
node.next.next = node;
node.next = null;
return previous;
}
private Node<T> reverse2(Node<T> head) {
Node<T> previous = null;
while (head != null) {
Node<T> temp = head.next;
head.next = previous;
previous = head;
head = temp;
}
return previous;
}
private void reverse3(Node<T> head) {
Stack<Node<T>> stack = new Stack<>();
while (head != null) {
stack.push(head);
head = head.next;
}
Node<T> first = null;
while (!stack.isEmpty()) {
Node<T> temp = stack.pop();
first.next = temp;
first = temp;
}
}
複製程式碼
查詢一個未知長度連結串列的中間項
private Node<T> findMiddle() {
Node<T> p = head;
Node<T> q = head;
while (q != null && q.next != null && q.next.next != null) {
p = p.next;
q = q.next.next;
}
return p;
}
複製程式碼
判斷兩個連結串列是否相交
private boolean isIntersect(Node<T> h1, Node<T> h2) {
if (h1 == null || h2 == null)
return false;
while (h1 != null) {
h1 = h1.next;
}
while (h2 != null) {
h2 = h2.next;
}
return h1 == h2;
}
複製程式碼
判斷連結串列是否有環,有環的話找出環的入口
private boolean isLoop() {
Node<T> fast = head;
Node<T> slow = head;
while (slow.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast)
return true;
}
return false;
}
private Node<T> findLoopNode() {
Node<T> fast = head;
Node<T> slow = head;
while (slow.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast)
break;
}
slow = head;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
複製程式碼