学习笔记-单链表面试题(有效节点个数,倒数第k个节点,反转,从尾打印,合并)

①求单链表中有效节点的个数(如果带头节点的链表,不统计头节点)

	//获取单链表的节点的个数(不带头节点)
	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;
        } 

②查找单链表中的倒数第K个节点

思路分析:从头开始遍历,得到总长度,从第一个开始遍历,(总长度-k)就可以得到
public static HeroNode findLastIndexNode(HeroNode head, int index) {
    if (head.next == null) {
        	   return null;
    	}
    	int size = getLength(head);//总长度
	if (index < 0 || index > size) { //校验
            return null;
    	}
    	//定义临时变量保存
    	HeroNode node = head.next;
    	//node为第一个有效数据,当循环第一次的时间就是第二个有效的数据,
    	//当总数据是3个,找倒数第一个,下面需要循环两次,实际是第三个,因为临时变量已经占用了一个
    	for (int i = 0; i < size - index; i++) {
        	    node = node.next;
    	}
    	return node;
	}

③单链表的反转

在这里插入图片描述

思路:(1)先定义一个节点,reverseHead = new HeroNode();
	(2)从头遍历原来的链表,每遍历一个节点,就将其取出,并放到新的链表reverseHead的最前端(始终放到最前面)
	(3)原来的链表的head.next = reverseHead.next
public static void reverseList(HeroNode head) {
    	if (head.next == null || head.next.next == null)    return;
    	HeroNode temp = head.next;//临时变量来遍历
    	HeroNode next = null;//指向当前节点(temp)的下一个节点
    	HeroNode reverse = new HeroNode(0,"","");
    	while (temp != null) {
            next = temp.next;//先保留当前节点的下一个节点,后面会用到
            temp.next = reverse.next;//首次将第一的下一个置为null
            reverse.next = temp;//连接新的链表
            temp = next;//后移
   	 	}
    	head.next = reverse.next;//将原链表指向新的链表
}

④从尾到头打印单链表

思路:
方式1:先将单链表进行反转操作,然后再遍历即可(破环原来链表的结构,不建议)
方式2:可以利用栈这个数据结构,将各个节点压入到栈中,利用栈的先进后出的特点,就实现了逆序打印的效果
//实现逆序打印的效果
	public static void reversePrint(HeroNode head) {
    	    if (head.next == null) {
             return;
   	 }
    	HeroNode temp = head.next;//临时变量
    	Stack<HeroNode> stack = new Stack<>();//创建所需的栈
    	//遍历放入栈中
    	while (temp != null) {
        	    stack.push(temp);
             temp = temp.next;
    	}
    	//遍历打印
    	while (stack.size() > 0) {
        	    System.out.println(stack.pop());
    	}
	}

⑤合并两个有序的单链表

在这里插入图片描述

思路分析:
1)获得head1和head2中数据值较小的节点,并设置为合并后链表的首节点
2)通过循环,依次获得链表1和链表2中数据值较小的节点,并添加到合并后链表的末尾
3)当步骤2执行完毕,如果某一个链表中的首节点不为null,则将该链表首节点及其之后的节点添加到合并后链表的末尾.
public static HeroNode mergeList(HeroNode node1, HeroNode node2) {
        if (node1.next == null && node2.next == null) {
            return null;
        }
        if (node1.next == null) {
            return node2;
        }
        if (node2.next == null) {
            return node1;
        }
        HeroNode heroNode = new HeroNode(0 ,"","");//新的链表
        //临时变量
        HeroNode node = heroNode;
        HeroNode temp1 = node1.next;
        HeroNode temp2 = node2.next;
        while (temp1 != null && temp2 != null) {
            if (temp1.no < temp2.no) {
                //取出链表1的值加入到新的链表中
                node.next = temp1;
                temp1 = temp1.next;
            } else {
                //取出链表2的值加入到新的链表中
                node.next = temp2;
                temp2 = temp2.next;
            }
            node = node.next;
        }
        if (temp1 == null) {
            node.next = temp2;
        }
        if (temp2 == null) {
            node.next = temp1;
        }
        return heroNode;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值