目錄
- 單鏈表倒數第k個節點
- 單鏈表反轉鏈表
- 單鏈表反向打印節點
單鏈表倒數第k個節點
/**
* 單鏈表倒數第k個節點
* 思路:1. 遍歷鏈表計算出,有效節點size(頭節點排除在外)
* 2. 倒數K節點對應的節點: size-k
* 解釋:例如鏈表:head(頭節點) -> A.next -> B.next ->C.next -> D.next
* head不是有效節點,所以head要排除在外
* 上述鏈表有效節點是4個,取倒數第2節點,即C節點,是我們需要的。
* size-k=2 從第一個有效節點,往後位移2位,即:從當前A節點,位移2位,是C節點。 即倒數k節點數據
* */
public void getK_Node(int k){
int size=getSize();
if (k<=0 || k>size){
return;
}
Node curNode = headNode.next;
for (int i=0;i<size-k;i++){
curNode=curNode.next;
}
log("倒數K節點數據 "+curNode);
}
public int getSize(){
int size=0;
Node curNode = headNode.next;
while (curNode != null) {
size++;
curNode = curNode.next;
}
return size;
}
單鏈表反轉鏈表
代碼實現
/**
* 單鏈表反轉
*/
public void reverse() {
// 分析1-->
if (headNode == null || headNode.next == null || headNode.next.next == null) {
// 空鏈表、鏈表只有一個元素 不用反轉
return;
}
Node temp = headNode;
Node reverseHead = new Node(0, "");
Node curNode = temp.next; // 當前鏈表
Node nextNode; // 臨時存儲當前鏈表的下一個鏈表元素
while (curNode != null) {
// 先保存當前鏈表位置的下一個元素
nextNode = curNode.next;
// 分析 2-->
/** 原鏈表:temp -> A.next -> B.next -> C.next ->D.next
* 核心思路:遍歷原鏈表時,每遍歷一個元素
* 1. next指針向後位移1位
* 2. 同時把鏈表當前位置的元素給插入到 頭節點是reverseHead的鏈表中,插在reverseHead最前端
* 2.1 把拿到的元素的next指向原本reverseHead.next指向的數據
* 2.2 然後把拿到當前的元素,都要插在新鏈表最前端:即:reverseHead.next指向的位置(頭節點後的第一個節點)
* 解釋: 例如當前是 reverseHead.next -> A.next
* 繼續遍歷拿到B時: 讓B.next ->A.next
* 在讓reverseHead.next ->B.next
* 這樣形成 reverseHead.next ->B.next -> A.next
* */
curNode.next = reverseHead.next;
reverseHead.next = curNode;
// 分析3 --> 把原鏈表中下一個節點元素,賦值給當前curNode。(就是鏈表向後位移一位)
curNode = nextNode;
}
//分析4 --> 原鏈表的頭節點指向新鏈表頭節點後的第一個元素(原表頭節點替換掉新表頭節點)
// 解釋 --> 新表頭節點,於後面的節點斷開,讓原表頭節點指向
temp.next = reverseHead.next;
// 最終完成單鏈表的反轉
try {
showNode();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
圖文解釋:
單鏈表反向打印節點
/**
* 單鏈表,反向打印節點
* 遍歷鏈表,逐個壓入棧中(棧的數據結構先進後),在遍歷棧,打印出來。結果符合反向打印鏈表
*/
public void reversePrint() {
Stack<Node> stack = new Stack<>();
Node curNode = headNode.next;
while (curNode != null) {
stack.push(curNode);
curNode = curNode.next;
}
while (stack.size() > 0) {
System.out.println("反向打印鏈表節點: " + stack.pop());
}
}
完整代碼
/**
* 帶頭節點的單鏈表
*/
public class LinkList {
Node headNode = new Node(0, "");
/**
* 不考慮客觀條件,直接插在鏈尾
*/
public void addNode(Node addNode) {
Node temp = headNode;
while (true) {
if (temp.next == null) { //找到最後一個節點
break;
}
temp = temp.next;
}
temp.next = addNode;
}
/**
* 按照順序節點插入 例:1 、2 、3、4、5
*/
public void addNodeByOrder(Node addNode) {
Node temp = headNode;
while (true) {
if (temp.next == null) {
break;
}
if (temp.next.num > addNode.num) { // A、B、C、D
break;
}
temp = temp.next;
}
addNode.next = temp.next;
temp.next = addNode;
}
/**
* 根據num 修改名字
*/
public void upNode(int num, String name) {
Node temp = headNode;
while (true) {
if (temp.next == null) {
System.out.println("upNode break 未找到可修改的數據");
break;
}
if (temp.next.num == num) {
temp.next.name = name;
System.out.println("upNode = " + temp.next.name);
break;
}
temp = temp.next;
}
}
/**
* delete
* 根據num刪除
*/
public void delete(int num) {
Node temp = headNode;
while (true) {
if (temp.next == null) {
System.out.println("delete break ");
break;
}
if (temp.next.num == num) {
// A、B、C B是刪除元素 A.next=C 即: A.next=A.next.next
System.out.println("delete的元素 " + temp.next);
temp.next = temp.next.next;
break;
}
temp = temp.next;
}
}
/**
* 根據num 查處 對應的Node
*/
public Node query(int num) {
Node temp = headNode;
Node tempNode = null;
while (true) {
if (temp.next == null) {
System.out.println("query break ");
break;
}
if (temp.next.num == num) {
tempNode = temp.next;
System.out.println("query = " + tempNode);
break;
}
temp = temp.next;
}
return tempNode;
}
/**
* 單鏈表反轉
*/
public void reverse() {
// 分析1-->
if (headNode == null || headNode.next == null || headNode.next.next == null) {
// 空鏈表、鏈表只有一個元素 不用反轉
return;
}
Node temp = headNode;
Node reverseHead = new Node(0, "");
Node curNode = temp.next; // 當前鏈表
Node nextNode; // 臨時存儲當前鏈表的下一個鏈表元素
while (curNode != null) {
// 先保存當前鏈表位置的下一個元素
nextNode = curNode.next;
// 分析 2-->
/** 原鏈表:temp -> A.next -> B.next -> C.next ->D.next
* 核心思路:遍歷原鏈表時,每遍歷一個元素
* 1. next指針向後位移1位
* 2. 同時把鏈表當前位置的元素給插入到 頭節點是reverseHead的鏈表中,插在reverseHead最前端
* 2.1 把拿到的元素的next指向原本reverseHead.next指向的數據
* 2.2 然後把拿到當前的元素,都要插在新鏈表最前端:即:reverseHead.next指向的位置(頭節點後的第一個節點)
* 解釋: 例如當前是 reverseHead.next -> A.next
* 繼續遍歷拿到B時: 讓B.next ->A.next
* 在讓reverseHead.next ->B.next
* 這樣形成 reverseHead.next ->B.next -> A.next
* */
curNode.next = reverseHead.next;
reverseHead.next = curNode;
// 分析3 --> 把原鏈表中下一個節點元素,賦值給當前curNode。(就是鏈表向後位移一位)
curNode = nextNode;
}
//分析4 --> 原鏈表的頭節點指向新鏈表頭節點後的第一個元素(原表頭節點替換掉新表頭節點)
// 解釋 --> 新表頭節點,於後面的節點斷開,讓原表頭節點指向
temp.next = reverseHead.next;
// 最終完成單鏈表的反轉
try {
showNode();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 單鏈表,反向打印節點
* 遍歷鏈表,逐個壓入棧中(棧的數據結構先進後),在遍歷棧,打印出來。結果符合反向打印鏈表
*/
public void reversePrint() {
Stack<Node> stack = new Stack<>();
Node curNode = headNode.next;
while (curNode != null) {
stack.push(curNode);
curNode = curNode.next;
}
while (stack.size() > 0) {
System.out.println("反向打印鏈表節點: " + stack.pop());
}
}
/**
* 單鏈表倒數第k個節點
* 思路:1. 遍歷鏈表計算出,有效節點size(頭節點排除在外)
* 2. 倒數K節點對應的節點: size-k
* 解釋:例如鏈表:head(頭節點) -> A.next -> B.next ->C.next -> D.next
* head不是有效節點,所以head要排除在外
* 上述鏈表有效節點是4個,取倒數第2節點,即C節點,是我們需要的。
* size-k=2 從第一個有效節點,往後位移2位,即:從當前A節點,位移2位,是C節點。 即倒數k節點數據
* */
public void getK_Node(int k){
int size=getSize();
if (k<=0 || k>size){
return;
}
Node curNode = headNode.next;
for (int i=0;i<size-k;i++){
curNode=curNode.next;
}
log("倒數K節點數據 "+curNode);
}
public int getSize(){
int size=0;
Node curNode = headNode.next;
while (curNode != null) {
size++;
curNode = curNode.next;
}
return size;
}
/**
* 打印出當前鏈表的所有元素
*/
public void showNode() throws InterruptedException {
if (headNode.next == null) { // 空
return;
}
Node temp = headNode.next; // 第一個元素
while (true) {
Thread.sleep(500);
System.out.println("showNode " + temp);
if (temp.next == null) {
System.out.println("showNode break ");
break;
}
temp = temp.next;
}
}
public static class Node {
int num;
String name;
Node next;
public Node(int num, String name) {
this.num = num;
this.name = name;
}
@Override
public String toString() {
return "Node{" +
"num=" + num +
", name='" + name +
'}';
}
}
}