求单链表中有效节点的个数:
不多说,直接上代码:
//求单链表中有效节点的个数(不包括头结点)
public static int getNodeLength(HeroNode head){
//判断链表是否为空
if (head.next == null){//链表为空
return 0;
}
//定义一个辅助变量
HeroNode cur = head.next; // head.next代表不带头节点
int length = 0;
while (cur != null){
length++;
//后移cur
cur = cur.next;
}
return length ;
}
查找单链表中的倒数第k个结点 【新浪面试题】:
思路分析:
倒数第k个 = 后移节点【有效节点个数(不带头结点) - k】次
- 编写一个方法,传入节点,以及index
- 遍历获取有效的节点个数size
- 得到size之后,进行for循环,0 ~size-index得出倒数第k个节点
- 返回该节点即可
// 查找单链表中倒数第k个节点
public static HeroNode findLastIndexNode(HeroNode head, int index) {
//首先判断链表是否为空
if (head.next == null) { //链表为空
return null;
}
//1.获取有效节点的个数
int size = getNodeLength(head);
//其次对index进行校验,如果输入不合法的index,return null
if (index <= 0 || index > size ){
return null;
}
//由于head不能动,定义一个辅助变量
HeroNode cur = head.next;
//2.遍历单链表,从第一个开始,到size-index, 移动cur (size-index)次,就能找到倒数第k个节点
for (int i = 0;i < size -index;i++){
cur =cur.next;
}
return cur ;
}
测试代码:
public static void main(String[] args) {
// 创建节点
HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
HeroNode hero3 = new HeroNode(3, "豹子头", "林冲");
HeroNode hero4 = new HeroNode(4, "花和尚", "鲁智深");
//创建链表:
singleLinkedList singleLinkedList = new singleLinkedList();
//按照排名顺序插入节点
singleLinkedList.addByOrder(hero2);
singleLinkedList.addByOrder(hero1);
singleLinkedList.addByOrder(hero4);
singleLinkedList.addByOrder(hero3);
System.out.println("遍历链表的情况:");
singleLinkedList.list();
singleLinkedList.del(2);
singleLinkedList.del(1);
System.out.println("删除链表之后的情况:======");
singleLinkedList.list();
//测试一下: 查找单链表中倒数第k个节点
System.out.println("倒数第一个节点是:"+ findLastIndexNode(singleLinkedList.getHead(),1));
System.out.println("倒数第二个节点是:"+ findLastIndexNode(singleLinkedList.getHead(),2));
}
带头结点的单链表反转:
思路分析:
- 先定义一个节点 reverseHead = new HeroNode();
- 从头到尾遍历原来的链表,每遍历一个节点,就将其取出,并放在新的链表reverseHead 的最前端.
- 原来的链表的head.next = reverseHead.next
代码实现:
//单链表的反转
public static void reverseList(HeroNode head){
//首先判断链表是否为空 或者链表是否只有一个节点
if (head.next ==null || head.next.next ==null){
return;
}
//定义一个辅助变量
HeroNode cur = head.next;
//定义一个变量用来存储当前节点的下一个节点
HeroNode next = null;
//创建一个反转节点
HeroNode reverseNode = new HeroNode(0,"","");
//TODO: 还没理解!
//遍历,循环
while (cur != null){
next = cur.next; //用来临时存储当前节点的下一个节点
cur.next = reverseNode.next; //将当前节点的下一个节点指向新节点的头
reverseNode.next = cur.next;
cur = next;//后移
}
head.next = reverseNode.next;
}
从 尾到头 打印单链表:
思路分析:
通过使用栈的先进后出实现。
1.遍历依次入栈
2.遍历依次出栈
代码实现:
//单链表:从 尾到头 打印单链表
public static void reversePrint(HeroNode head){
//判断 链表是否为空
if (head.next == null){
return;
}
//定义一个辅助变量,由于head不能动
HeroNode cur = head.next;
Stack<HeroNode> stack= new Stack<>();
while (cur != null){
stack.push(cur);
cur = cur.next;
}
//输出
while (stack.size() > 0){
System.out.println(stack.pop());
}
}
最后测试代码以及运行效果:
public class SingleLinkedListDemo {
public static void main(String[] args) {
// 创建节点
HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
HeroNode hero3 = new HeroNode(3, "豹子头", "林冲");
HeroNode hero4 = new HeroNode(4, "花和尚", "鲁智深");
//创建链表:
singleLinkedList singleLinkedList = new singleLinkedList();
//按照排名顺序插入节点
singleLinkedList.addByOrder(hero2);
singleLinkedList.addByOrder(hero1);
singleLinkedList.addByOrder(hero4);
singleLinkedList.addByOrder(hero3);
System.out.println("遍历原先链表的情况:");
singleLinkedList.list();
//测试一下单链表 从尾到头打印输出
reversePrint(singleLinkedList.getHead());
}
运行效果: