单链表面试题总结

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一、题目

单链表面试题如下:

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

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

二、题解

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

    //输出单链表中有效节点的个数
    public int listNum(){
        if(head.next==null){
            System.out.println("无法遍历链表,链表为空!");
            return -1;
        }
        HeroNode2 temp = head;
        int sum=0;
        while (true){
            if (temp.next==null){
                break;
            }
            temp=temp.next;
            sum+=1;
        }
        return sum;
    }

在这里插入图片描述

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

//    查找单链表中倒数第k个节点【新浪面试题】
    public void getNode(int k){
        if(head.next==null){
            System.out.println("链表为空");
            return;
        }
        HeroNode2 temp = head.next;
        int length = listNum();//4
        if(k<=0||k>length){
            System.out.println("无此节点");
        }
        int key = length-k+1;//k=2  4-2+1
        while(key>1){
            temp = temp.next;
            key--;
        }
        System.out.println(temp);
    }

在这里插入图片描述

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

    //单链表的反转
    public void ReverseLinkedList(){
        if(head.next==null){
            System.out.println("链表为空");
            return;
        }
        HeroNode2 reverseNode = new HeroNode2(0,"");
        HeroNode2 cur = head.next;
        HeroNode2 temp = null;
        while(cur!=null){
            temp = cur.next;
            cur.next = reverseNode.next;
            reverseNode.next=cur;
            cur=temp;
        }
        head.next = reverseNode.next;
    }

在这里插入图片描述

4.从尾到头打印单链表

利用栈的先进后出的特点

利用栈的数据结构,将各个节点压入到栈中,然后利用栈的先进后出的特点,实现逆序打印

    //单链表逆序输出,使用Stack栈
    public void listByStack(){
        if(head.next==null){
            System.out.println("单链表为空");
            return;
        }
        HeroNode2 temp = head;
        Stack<HeroNode2> stack = new Stack<>();
        while (temp.next!=null){
            stack.add(temp.next);
            temp=temp.next;
        }
        while (stack.size()>0){
            System.out.println(stack.pop());
        }
    }

在这里插入图片描述

5.合并两个有序的单链表,合并之后的链表依然有序

我们可以使用双指针算法来破解

    //合并两个单链表,合并之后依然有序
    public LinkedListMove TwoToOne(LinkedListMove list1,LinkedListMove list2,int size1,int size2){
        LinkedListMove list3 = new LinkedListMove();
        HeroNode2 temp1 = list1.head.next;
        HeroNode2 temp2 = list2.head.next;
        HeroNode2 temp3 = list3.head;
        while(temp1!=null||temp2!=null){
            if(temp1==null){
                //此时temp2不为空,将temp2中的所有数据放到temp3后面即可
                while (temp2!=null){
                    temp3.next=temp2;
                    temp3 = temp3.next;
                    temp2 = temp2.next;
                }
                break;
            }
            if(temp1==null){
                //此时temp2不为空,将temp2中的所有数据放到temp3后面即可
                while (temp1!=null){
                    temp3.next=temp1;
                    temp3 = temp3.next;
                    temp1 = temp1.next;
                }
                break;
            }
            if(temp1.no<temp2.no){
                temp3.next=temp1;
                temp3 = temp3.next;
                temp1 = temp1.next;
                continue;
            }
            if(temp2.no<temp1.no){
                temp3.next=temp2;
                temp3 = temp3.next;
                temp2 = temp2.next;
                continue;
            }
        }
        return list3;
    }

在这里插入图片描述

全部代码

package org.wql.LinkedList;

import java.util.Stack;

/**
 * Description
 * User:
 * Date:
 * Time:
 */
public class SingleLinkedListTest {
    public static void main(String[] args) {
        HeroNode2 hero1 = new HeroNode2(1, "aaa");
        HeroNode2 hero3 = new HeroNode2(3, "ccc");
        HeroNode2 hero7 = new HeroNode2(7, "ccc");
        HeroNode2 hero8 = new HeroNode2(8, "ccc");


        HeroNode2 hero2 = new HeroNode2(2, "bbb");
        HeroNode2 hero4 = new HeroNode2(4, "ddd");
        HeroNode2 hero9 = new HeroNode2(9, "ccc");
        HeroNode2 hero11 = new HeroNode2(11, "ccc");

        LinkedListMove list1 = new LinkedListMove();
        list1.add(hero1);
        list1.add(hero3);
        list1.add(hero7);
        list1.add(hero8);

        LinkedListMove list2 = new LinkedListMove();
        list2.add(hero2);
        list2.add(hero4);
        list2.add(hero9);
        list2.add(hero11);

        System.out.println("单链表1:");
        list1.list();
        System.out.println("单链表2:");
        list2.list();
        System.out.println("利用双指针算法合并:");
        LinkedListMove list3 = list1.TwoToOne(list1, list2, 4, 4);
        list3.list();

//        LinkedListMove linkedListMove = new LinkedListMove();
//        linkedListMove.add(hero1);
//        linkedListMove.add(hero2);
//        linkedListMove.add(hero3);
//        linkedListMove.add(hero4);

//        System.out.println("求单链表中有效节点的个数");
//        int length = linkedListMove.listNum();
//        System.out.println("有效个数为:"+length);
    }
}
//对联表进行操作的类
class LinkedListMove{
    //头节点
    HeroNode2 head = new HeroNode2(0,"");
    //在结尾添加节点
    public void add(HeroNode2 node){
        HeroNode2 temp = head;
        while (true){
            if (temp.next==null){
                temp.next=node;
                break;
            }
            temp=temp.next;
        }
    }
    //按照顺序添加节点
    public void addByOrder(HeroNode2 node){
        HeroNode2 temp = head;
        while (true){
            if(temp.next==null){
                add(node);
                break;
            }
            if(temp.next.no>node.no){
                node.next=temp.next;
                temp.next=node;
                break;
            }
            temp=temp.next;
        }
    }
    //遍历单链表
    public void list(){
        if(head.next==null){
            System.out.println("无法遍历链表,链表为空!");
            return;
        }
        HeroNode2 temp = head;
        while (true){
            if (temp.next==null){
                break;
            }
            temp=temp.next;
            System.out.println(temp);
        }
    }
    //输出单链表中有效节点的个数
    public int listNum(){
        if(head.next==null){
            System.out.println("无法遍历链表,链表为空!");
            return -1;
        }
        HeroNode2 temp = head;
        int sum=0;
        while (true){
            if (temp.next==null){
                break;
            }
            temp=temp.next;
            sum+=1;
        }
        return sum;
    }
//    查找单链表中倒数第k个节点【新浪面试题】
    public void getNode(int k){
        if(head.next==null){
            System.out.println("链表为空");
            return;
        }
        HeroNode2 temp = head.next;
        int length = listNum();//4
        if(k<=0||k>length){
            System.out.println("无此节点");
        }
        int key = length-k+1;//k=2  4-2+1
        while(key>1){
            temp = temp.next;
            key--;
        }
        System.out.println(temp);
    }
    //单链表的反转
    public void ReverseLinkedList(){
        if(head.next==null){
            System.out.println("链表为空");
            return;
        }
        HeroNode2 reverseNode = new HeroNode2(0,"");
        HeroNode2 cur = head.next;
        HeroNode2 temp = null;
        while(cur!=null){
            temp = cur.next;
            cur.next = reverseNode.next;
            reverseNode.next=cur;
            cur=temp;
        }
        head.next = reverseNode.next;
    }
    //单链表逆序输出方式一
    public void sysLinkedList(){
        if(head.next==null){
            System.out.println("链表为空");
            return;
        }
        HeroNode2 reverseNode = new HeroNode2(0,"");
        HeroNode2 cur = head.next;
        HeroNode2 temp = null;
        while(cur!=null){
            temp = cur.next;
            cur.next = reverseNode.next;
            reverseNode.next=cur;
            cur=temp;
        }
        System.out.println(reverseNode.next);
    }
    //单链表逆序输出方式二,使用栈
    public void listByStack(){
        if(head.next==null){
            System.out.println("单链表为空");
            return;
        }
        HeroNode2 temp = head;
        Stack<HeroNode2> stack = new Stack<>();
        while (temp.next!=null){
            stack.add(temp.next);
            temp=temp.next;
        }
        while (stack.size()>0){
            System.out.println(stack.pop());
        }
    }
    //合并两个单链表,合并之后依然有序
    public LinkedListMove TwoToOne(LinkedListMove list1,LinkedListMove list2,int size1,int size2){
        LinkedListMove list3 = new LinkedListMove();
        HeroNode2 temp1 = list1.head.next;
        HeroNode2 temp2 = list2.head.next;
        HeroNode2 temp3 = list3.head;
        while(temp1!=null||temp2!=null){
            if(temp1==null){
                //此时temp2不为空,将temp2中的所有数据放到temp3后面即可
                while (temp2!=null){
                    temp3.next=temp2;
                    temp3 = temp3.next;
                    temp2 = temp2.next;
                }
                break;
            }
            if(temp1==null){
                //此时temp2不为空,将temp2中的所有数据放到temp3后面即可
                while (temp1!=null){
                    temp3.next=temp1;
                    temp3 = temp3.next;
                    temp1 = temp1.next;
                }
                break;
            }
            if(temp1.no<temp2.no){
                temp3.next=temp1;
                temp3 = temp3.next;
                temp1 = temp1.next;
                continue;
            }
            if(temp2.no<temp1.no){
                temp3.next=temp2;
                temp3 = temp3.next;
                temp2 = temp2.next;
                continue;
            }
        }
        return list3;
    }
}
class HeroNode2{
    int no;
    String  name;
    HeroNode2 next;

    public HeroNode2(int no, String name) {
        this.no = no;
        this.name = name;
    }

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

温文艾尔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值