链表的定义:
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;
}