目录
- 单链表倒数第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 +
'}';
}
}
}