面试题:求单链表中有效节点的个数和查找单链表中的倒数第k个节点,单链表的反转以及单链表逆序输出

求单链表中有效节点的个数:

不多说,直接上代码:
 //求单链表中有效节点的个数(不包括头结点)
    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】次

  1. 编写一个方法,传入节点,以及index
  2. 遍历获取有效的节点个数size
  3. 得到size之后,进行for循环,0 ~size-index得出倒数第k个节点
  4. 返回该节点即可
// 查找单链表中倒数第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));
        }

带头结点的单链表反转:

思路分析:

  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 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());

    }

运行效果:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值