1. 求单链表中有效结点的个数
/**
* 获取单链表的有效结点个数(头结点不算)
* @param head 链表头结点
* @return 有效节点个数
*/
public static int getLength(HeroNode head) {
if(head.next == null)
return 0;
int length = 0;
// 定义临时变量, 用于遍历链表
HeroNode cur = head.next;
while(cur != null) {
length++;
cur = cur.next;
}
return length;
}
2. 查找单链表中倒数第k个结点
/**
* 查找单链表中的倒数第k个结点
* @param head 链表头结点
* @param lastIndex 倒数索引
* @return 找到则对应位置的结点; 否则返回null
*/
public static HeroNode getNodeByLastIndex(HeroNode head, int lastIndex) {
if(head.next == null)
return null;
// 1. 遍历, 得到链表总长度
int length = getLength(head);
// 2. 校验lastIndex
if(lastIndex <= 0 || lastIndex > length)
return null;
// 目标结点之前的结点个数
int count = length - lastIndex;
// 3. 从 首结点(第1个结点) 开始遍历, 移动 count 次, 到达 [倒数第k个结点]
HeroNode cur = head.next;
for(int i = 0; i < count; i++)
cur = cur.next;
return cur;
}
3. 反转链表
/**
* 链表反转
* @param head 单链表的头结点
*/
public static void reverseList(HeroNode head) {
// 0. 如果当前链表为空 / 只有一个结点, 则无须反转
if(head.next == null || head.next.next == null)
return;
// 1. 定义一个反转链表头结点 reverseHead
HeroNode reverseHead = new HeroNode(0,"","");
// 指向当前遍历到的结点
HeroNode cur = head.next;
// 存放 当前遍历到的结点cur 的 next结点
HeroNode next;
// 2. 从头到尾遍历原来的链表, 每遍历到一个结点, 就将其取出, 放在新链表的最前面
while(cur != null) {
// 保存下一个要访问的结点地址
next = cur.next;
// 把 当前结点 链接到 反转链表
cur.next = reverseHead.next;
reverseHead.next = cur;
// 结点后移
cur = next;
}
// 3. 让原链表的head.next = reverseHead.next
head.next = reverseHead.next;
}
4. 逆序打印单链表(要求不改变链表本身的结构)
/**
* 逆序打印单链表(栈:先进后出)
* @param head 头结点
*/
public static void reversePrintList(HeroNode head) {
if(head.next == null)
return;
// 创建一个栈, 将结点压入栈中
Stack<HeroNode> stack = new Stack<>();
HeroNode cur = head.next;
while (cur != null) {
stack.push(cur);
cur = cur.next;
}
while (stack.size() > 0)
System.out.println(stack.pop());
}