鏈表的定義:
public class myLinkedList {
public Node head = null;
class Node {
public int value;
public Node next = null;
Node(int value) {
this.value = value;
}
}
}
添加一個節點:
public void addNode(int value) {
Node newNode = new Node(value);
if (head == null) {
head = newNode;
return;
}
Node temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = newNode;
}
根據序號刪除一個節點:
public boolean deleteNodebyIndex(int index) {
if (head == null || index < 1) {
return false;
}
if (index == 1) {
head = head.next;
return true;
}
Node preNode = head;
Node currNode = head.next;
int cnt = 2;
while (cnt != index) {
preNode = currNode;
currNode = currNode.next;
//需要刪除的序號大於鏈表長度
if (currNode == null) {
return false;
}
cnt += 1;
}
preNode.next = currNode.next;
return true;
}
根據值刪除一個節點:
public boolean deleteNodebyValue(int value) {
if (head == null) {
return false;
}
if (head.value == value) {
head = head.next;
return true;
}
Node preNode = head;
Node currNode = head.next;
if (currNode == null) {
return false;
}
while (currNode.value != value) {
preNode = currNode;
currNode = currNode.next;
if (currNode == null) {
return false;
}
}
preNode.next = currNode.next;
return true;
}
返回鏈表的長度:
public int length() {
int len = 0;
Node temp = head;
while (temp != null) {
len++;
temp = temp.next;
}
return len;
}
打印整個鏈表:
public void printList() {
Node temp = head;
while (temp != null) {
System.out.print(temp.value + " ");
temp = temp.next;
}
System.out.println();
}
反轉鏈表:
public void ReverseIteratively() {
if (head == null) {
return;
}
if (head.next == null) {
return;
}
Node node1 = head;
Node node2 = node1.next;
Node node3 = node2.next;
while (node3 != null) {
node2.next = node1;
node1 = node2;
node2 = node3;
node3 = node3.next;
}
node2.next = node1;
head.next = null;
head = node2;
}
尋找鏈表的中間節點,快慢指針,p1先走2步,p2走1步,當p1無法繼續走時,p2就是中間的節點:
public Node SearchMid() {
Node node_slow = head;
Node node_fast = head;
while (node_fast != null && node_fast.next != null && node_fast.next.next != null) {
node_fast = node_fast.next.next;
node_slow = node_slow.next;
}
return node_slow;
}
查找倒數第k個元素,p1先走k步,然後p1、p2同時走,無法繼續走時,p2就是所找的節點:
public Node findElem(int k) {
Node node1 = head;
Node node2 = head;
for (int i = 1; i < k; i++) {
node1 = node1.next;
}
while (node1.next != null) {
node1 = node1.next;
node2 = node2.next;
}
return node2;
}
對鏈表進行排序(插入排序):
public void orderList() {
Node guard = new Node(Integer.MIN_VALUE);
guard.next = head;
Node preNode = guard;
Node curNode = guard.next;
while (curNode != null) {
if (curNode.value >= preNode.value) {
preNode = curNode;
curNode = curNode.next;
} else {
preNode.next = curNode.next;
Node temp = guard;
Node pretemp = guard;
while (temp.value < curNode.value) {
pretemp = temp;
temp = temp.next;
}
pretemp.next = curNode;
curNode.next = temp;
curNode = preNode.next;
}
}
head = guard.next;
}
從尾到頭輸出單鏈表,採用遞歸方式實現:
public void printListReversely(Node node) {
if (node != null) {
printListReversely(node.next);
System.out.print(node.value + " ");
}
}
判斷鏈表是否有環,快慢指針,如果有環,在環上速度不同的指針一定會相遇,複雜度爲環的長度:
public boolean IsLoop() {
Node fast = head;
Node slow = head;
if (fast == null) {
return false;
}
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) {
return true;
}
}
return true;
}
找出鏈表環的入口:
public Node FindLoopPort() {
Node fast = head, slow = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast)
break;
}
if (fast == null || fast.next == null)
return null;
slow = head;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
return slow;
}