面试题———————单链表

学习完单链表后趁热打铁做了几道面试题。(点击链接可以查看上一篇单链表学习)
以下1-5题难度依次递增,每道题的思路和实现过程将详细的展示。

  1. 求单链表中节点的个数
  2. 查找单链表中的倒数第k个节点【新浪面试题】
  3. 单链表的反转 【腾讯面试题】
  4. 从尾到头打印单链表【百度,要求方式1:反向遍历,方式2:Stack栈】
  5. 合并两个有序的单链表,合并之后的链表依然有序

完成每道题之前,可以通过自己的理解去完成,下面我仅说出我的思路分析和代码的实现过程

01求单链表中节点的个数

思路分析:

1.判断是否为空
2.循环遍历——如果辅助节点的next不等于null 就length++
具体代码:

   /**
    * @param head 头节点
    * @return 返回的是单链表有效节点的个数
    */
   public static int findSingleLinkLength(HeroNode head) {
    
    
       //辅助节点
       HeroNode cur = head.next;
       if (cur == null) {
    
    
           return 0;
       }
       //定义一个变量接收节点的个数
       int length = 0;
       while (cur != null) {
    
    
           //后移 接着遍历寻找
           cur = cur.next;
           length++;
       }
       return length;
   }

代码测试:

public class SingleLinkedListDemo {
    
    
   public static void main(String[] args) {
    
    
       SingleLinkedList singleLinkedList = new SingleLinkedList();
       HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
       HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
       HeroNode hero3 = new HeroNode(3, "吴用", "智多星");
       HeroNode hero4 = new HeroNode(4, "林冲", "豹子头");
       HeroNode hero5 = new HeroNode(5, "李逵", "黑旋风");
       //添加英雄
       singleLinkedList.add(hero1);
       singleLinkedList.add(hero3);
       singleLinkedList.add(hero5);
       singleLinkedList.add(hero2);
   	
   	   //测试单链表有效节点的个数
       int length = findSingleLinkLength(singleLinkedList.getHead());
       System.out.println("length=" + length);
   }
}

测试结果:

length=4

02查找单链表中的倒数第k个节点【新浪面试题】

思路分析:
1.通过(总节点数-目标节点数)去循环遍历
例如: 一共4个节点 现在要查找倒数第3个节点 做法是通过循环(4-3)此找到此节点,其中4是通过调用方法 findSingleLinkLength得到,3为用户传入的数值。
具体代码:

    //查找单链表中倒数第K个节点【新浪面试】
    public static HeroNode findHeroNode(HeroNode head, int no) {
    
    
        //定义辅助节点指向第一个节点
        HeroNode cur = head.next;
        //找出总的节点数
        int size = findSingleLinkLength(head);
        //对传入的no进行校验 
        //不存在倒数第0个节点的说法 也不存在要查找的节点数大于总节点数
        if (no <= 0 || no > size) {
    
    
            return null;
        }
        //循环遍历 假如 3个节点  查找倒数第二个节点 3-2=1
        for (int i = 0; i < size - no; i++) {
    
    
        	//后移
            cur = cur.next;
        }
        return cur;
    }

代码测试:

 public class SingleLinkedListDemo {
    
    
    public static void main(String[] args) {
    
    
        SingleLinkedList singleLinkedList = new SingleLinkedList();
        HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
        HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
        HeroNode hero3 = new HeroNode(3, "吴用", "智多星");
        HeroNode hero4 = new HeroNode(4, "林冲", "豹子头");
        HeroNode hero5 = new HeroNode(5, "李逵", "黑旋风");
        //添加英雄
        singleLinkedList.add(hero1);
        singleLinkedList.add(hero3);
        singleLinkedList.add(hero5);
        singleLinkedList.add(hero2);
        //测试单链表中倒数第K个节点
        int no = 3;
        HeroNode heroNode = findHeroNode(singleLinkedList.getHead(), no);
        System.out.printf("倒数第%d节点", no);
        System.out.println(heroNode);
    }
}

测试结果:

倒数第3个节点HeroNode{no=3, name=‘吴用’, nickname=‘智多星’}

03单链表的反转 【腾讯面试题】

思路分析:
1.先定义一个节点 HeroNode reverse = new HeroNode(0,"","");
2.从头到尾遍历原来的链表,每遍历一个节点,就将其取出,并放在新的链表reverseHead的最前端
3.原来的链表的head.next = reverseHead.next

 //单链表的反转
    public static void reverseSingleLink(HeroNode head) {
    
    
        //没有节点或者只存在一个节点
        if (head.next == null || head.next.next == null) {
    
    
            return;
        }
        //创建一个新的单链表
        HeroNode reverseHead = new HeroNode(0,"","");
        //定义一个辅助变量,帮助我们遍历原来的链表
        HeroNode cur = head.next;
        HeroNode next = null;//指向当前节点的下一个节点

        while (cur != null) {
    
    
            //保留当前节点的下一个节点
            next = cur.next;
            //cur的下一个节点指向新链表的前端
            cur.next = reverseHead.next;
            //将cur连接到新的链表上
            reverseHead.next = cur;
            cur = next;//节点后移
        }
        //将 head.next 指向 reverseHead.next 实现单链表的反转
        head.next = reverseHead.next;
    }

代码测试:

public class SingleLinkedListDemo {
    
    
    public static void main(String[] args) {
    
    
        SingleLinkedList singleLinkedList = new SingleLinkedList();
        HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
        HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
        HeroNode hero3 = new HeroNode(3, "吴用", "智多星");
        HeroNode hero4 = new HeroNode(4, "林冲", "豹子头");
        HeroNode hero5 = new HeroNode(5, "李逵", "黑旋风");
        //添加英雄
        singleLinkedList.add(hero1);
        singleLinkedList.add(hero3);
        singleLinkedList.add(hero5);
        singleLinkedList.add(hero2);
        System.out.println("反转前的链表");
        singleLinkedList.list();
 		System.out.println("测试反转后的链表");
        reverseSingleLink(singleLinkedList.getHead());
        singleLinkedList.list();
    }
}

测试结果:

反转前的链表
HeroNode{no=1, name=‘宋江’, nickname=‘及时雨’}
HeroNode{no=3, name=‘吴用’, nickname=‘智多星’}
HeroNode{no=5, name=‘李逵’, nickname=‘黑旋风’}
HeroNode{no=2, name=‘卢俊义’, nickname=‘玉麒麟’}
测试反转后的链表
HeroNode{no=2, name=‘卢俊义’, nickname=‘玉麒麟’}
HeroNode{no=5, name=‘李逵’, nickname=‘黑旋风’}
HeroNode{no=3, name=‘吴用’, nickname=‘智多星’}
HeroNode{no=1, name=‘宋江’, nickname=‘及时雨’}

04从尾到头打印单链表【百度,要求方式1:反向遍历,方式2:Stack栈】

思路分析:
1.利用栈先进后出的特点,实现逆序打印效果。

栈的基本用法:入栈、出栈

	    Stack<String> stack = new Stack<>();
        //入栈
        stack.push("张三");
        stack.push("王五");
        stack.push("赵六");
        //出栈
        while (stack.size() > 0){
    
    
            System.out.println(stack.pop());
        }

打印结果:

赵六
王五
张三

实现栈的逆序打印:

 //实现链表的逆序打印
    public static void reversePrint(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());
        }
    }

代码测试:

public class SingleLinkedListDemo {
    
    
    public static void main(String[] args) {
    
    
        SingleLinkedList singleLinkedList = new SingleLinkedList();
        HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
        HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
        HeroNode hero3 = new HeroNode(3, "吴用", "智多星");
        HeroNode hero4 = new HeroNode(4, "林冲", "豹子头");
        HeroNode hero5 = new HeroNode(5, "李逵", "黑旋风");
        //添加英雄
        singleLinkedList.add(hero1);
        singleLinkedList.add(hero3);
        singleLinkedList.add(hero5);
        singleLinkedList.add(hero2);

        //循环遍历
        System.out.println("单链表的信息");
        singleLinkedList.list();

        System.out.println("测试逆序打印链表");
        reversePrint(singleLinkedList.getHead());
    }
}

测试结果:

单链表的信息
HeroNode{no=1, name=‘宋江’, nickname=‘及时雨’}
HeroNode{no=3, name=‘吴用’, nickname=‘智多星’}
HeroNode{no=5, name=‘李逵’, nickname=‘黑旋风’}
HeroNode{no=2, name=‘卢俊义’, nickname=‘玉麒麟’}
测试逆序打印链表
HeroNode{no=2, name=‘卢俊义’, nickname=‘玉麒麟’}
HeroNode{no=5, name=‘李逵’, nickname=‘黑旋风’}
HeroNode{no=3, name=‘吴用’, nickname=‘智多星’}
HeroNode{no=1, name=‘宋江’, nickname=‘及时雨’}

以上就是单链表的一些面试题。方法不是唯一的可以尝试多种方法。

猜你喜欢

转载自blog.csdn.net/lirui1212/article/details/111188531