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

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

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;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/zjdzka/article/details/109755357