单链表大厂面试题解(韩顺平老师版)

20 篇文章 0 订阅

单链表大厂面试题(手撕代码环节)

1.查看链表倒数第k个节点

//查看链表倒数第k个节点(新浪面试)
//思路:1.编写一个方法,接收head节点,同时接收index 节点
//     2.index 表示倒数第 index 个节点
//     3.先把链表从头到尾遍历,得到链表的总长度
//     4.得到size后,我们从链表第一个开始遍历,遍历(size - index)个
//     5.如果找到返回该节点,找不到返回空

public static Student findLastIndexStudent(Student head,int index){
    //判断链表为空
    if(head.next==null){
        return null;
    }
    int size = getLength(head);
    //做一个index校验
    if(index <= 0 || index >size){
        return null;
    }
    //定义一个辅助遍历,for循环定位到index位置上
    Student temp = head.next;
    for(int i=0;i<size-index;i++){
        temp=temp.next;
    }
    return temp;
}

2.逆转单链表

//将单链表逆转(腾讯面试)
//思路:1.先定义一个新的节点,当新链表的头节点
//     2.遍历旧的链表,每次遍历到一个节点就将其拿出,放到新的链表中
//     3.接下来每次遍历取出的节点,都放到之前那个节点的前面插入
//     4.最后将原始的头节点指向新的链表的节点
public static void ReverseList(Student head){
    //判断链表是否为空,或者只有一个节点则无需逆序
     if(head.next == null || head.next.next ==null){
         return  ;
     }
     Student ReverseHead = new Student(0,"",0);
Student temp = head.next;//原链表的辅助指针
Student temp1 = null; //指向当前节点temp下一个节点
         while (temp != null) {
                      temp1 = temp.next;//暂时保存当前节点的下一个节点,后面要使用
                      temp.next = ReverseHead.next;//将temp的下一个节点指向新链表的最前端
                      ReverseHead.next = temp ;//将temp连接到新的链表上
                      temp = temp1;//将temp后移
                             }
     head.next=ReverseHead.next;
}

3.单链表逆序打印

//将单链表逆序打印,不能破坏结构(百度面试)
//思路:使用栈的思想,先进后出
public static void ReversePrint(Student head){
    //判断链表是否为空
    if(head.next == null ){
        return  ;
    }
    //创建一个栈,将各个节点压入栈中
Stack<Student> stack  = new Stack<Student>();
Student temp = head.next;
//将各个节点压入
while (temp != null){
    stack.push(temp);
    temp= temp.next;//后移
}
//打印栈中的节点
        while (stack.size()>0){
            System.out.println(stack.pop());
        }
    }
}

4.完整代码如下:

public class SingleLinkedListDemo {
    public static void main(String[] args) {
        Student student1 = new Student(1,"tom",18);
        Student student2 = new Student(2,"kiki",19);
        Student student3 = new Student(3,"lily",19);
        Student student4 = new Student(4,"lion",20);
        //创建要给的链表
       SingleLinkedList1 singleLinkedList1 = new SingleLinkedList1();
       singleLinkedList1.add(student2);
       singleLinkedList1.add(student4);
       singleLinkedList1.add(student1);
       singleLinkedList1.add(student3);
       singleLinkedList1.showInfo();
       System.out.println("____________________");
       System.out.println(getLength(singleLinkedList1.getHead()));
       //测试查看倒数第k个节点:
       Student res = findLastIndexStudent(singleLinkedList1.getHead(),1);
       System.out.println(res);
       System.out.println("_____________________________");
       //测试单链表的逆序
       ReverseList(singleLinkedList1.getHead());
       singleLinkedList1.showInfo();
      //测试逆序打印单链表(不改变结构)
      System.out.println("____________________________");
      ReversePrint(singleLinkedList1.getHead());
      }

//获取节点的个数
/**
 *
 * @param head 头节点
 * @return  返回有效节点个数
 */
public static  int getLength(Student head) {
    Student temp = head.next;
    int length = 0;
    if (head.next == null) {
        System.out.println("这是一个空链表");
        return 0;
    }
    while (temp != null) {
        length++;
        temp = temp.next;
    }
    return length;
}


class Student{//定义学生类
    public int no;
    public String name;
    public int age;
    public Student next;//指向下一个节点

    //有参构造
    public Student(int no,String name,int age){
        this.no = no;
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", age=" + age +'\''+
                '}';
    }
}

//定义单链表,管理学员信息
class SingleLinkedList1{
    //初始化头节点,头节点不能动,不存放数据
    private Student head = new Student(0,"",0);

    //返回头节点
    public Student getHead(){
        return head;
    }
    //分析:添加节点到链表:
    public void add(Student student){
        //创建一个辅助指针
        Student temp = head;
        boolean flag = false;
        while (true){
            if(temp.next == null){
                break;//链表已经到了最后
            }
            if(temp.next.no >student.no ){
        //位置找到,在temp后插入
        break;
    }else  if(temp.next.no == student.no){//要添加的no已经存在,添加失败
        flag =true;
        break;
    }
    temp=temp.next;
}
//flag判断
    if(flag){
        System.out.print("准备添加的 %d  已经存在,添加失败");
    }else{
        //加入链表
        student.next =temp.next;
        temp.next = student;
    }
}
//显示
    public void showInfo(){
    //判断链表是否为空
        if(head.next == null){
            System.out.println("链表为空");
                return;
        }
        //仍然创建一个辅助指针,头节点不能动
        Student temp = head.next;
        while (true){
            if(temp==null){
                break;//判断链表是否到最后
            }
            //输出节点信息
            System.out.println(temp);
            //将temp后移
            temp = temp.next;
        }
    }
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值