数据结构和算法之单链表练习

数据结构和算法之单链表练习

三道大厂面试题:

【新浪面试题】查找单链表中的倒数第k个结点
【腾讯面试题】单链表的反转
【百度面试题】从尾到头打印单链表

1、先上神器:

lombok,在pom里面加入依赖,并在idea中下载lombok插件,然后就可以直接使用啦~

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
        </dependency>

2、用一个heroNode类模拟节点

@Data
@NoArgsConstructor
class HeroNode{
    private int no;
    private String name;
    private String nickname; //昵称
    private HeroNode next;//指向下一个节点编号

    public HeroNode(int no, String name, String nickname) {
        this.no = no;
        this.name = name;
        this.nickname = nickname;
    }
    public String toString(){
        return"HeroNode[no="+no+",name="+name+",nickname="+nickname+"]";
        //重写tostring方法,方便展示输出数据
    }
}

3、单链表方法的实现

//链表操作
class SingleLinkedTest{
    //链表的头部固定,定义一个头节点,数据为空
    private HeroNode head = new HeroNode(0,"","");
    public HeroNode getHead() {
        return head;
    }

    //将节点挂上链表
    public void addNode(HeroNode heroNode){
        //先找到尾节点,然后把新节点挂到尾节点上
        //定义辅助节点temp
        HeroNode temp  = head;
        while (true){
            if (temp.getNext() == null){ //当辅助节点的下一个节点为空时,表示找到了最后一个节点
                break;
            }
            temp = temp.getNext();
        }
        temp.setNext(heroNode);
    }

    //有序的将节点加入链表
    public void addOrderNode(HeroNode heroNode){
        //定义辅助节点temp
        HeroNode temp  = head;
        while (true){
            if (temp.getNext() == null){ //当辅助节点的下一个节点为空时,表示已经到了最后一个节点
                temp.setNext(heroNode);
                break;
            }
            //当辅助节点的下一个节点的编号大于当前编号,则找到了插入的位置
            if (heroNode.getNo() < temp.getNext().getNo()){
                heroNode.setNext(temp.getNext());
                temp.setNext(heroNode);
                break;
            }
            temp = temp.getNext();

        }
    }

    //获取节点个数,不包括头结点
    public void getNodeCount(){
        HeroNode temp = head;
        int count = 0;
        while (true){
            if (temp.getNext() == null){
                break;
            }
            count++;
            temp = temp.getNext();
        }
        System.out.println("节点的个数为:"+count);
    }

    //节点反转
    public SingleLinkedTest reversalLink(SingleLinkedTest singleLinkedTest){
        SingleLinkedTest singleLinkedTestTemp = new SingleLinkedTest();
        HeroNode temp ;//辅助节点
        HeroNode temp01 = singleLinkedTest.getHead().getNext(); //要反转链表的头部
        while (true){
            if (temp01 == null){
                break; //旧链表空了,表示全部反转完了
            }
            //反转链接,所以所有新获取的节点,每次都放到head后面
            temp = singleLinkedTestTemp.getHead().getNext(); //总是指向新链表的下一个节点
            singleLinkedTestTemp.getHead().setNext(temp01);
            temp01=temp01.getNext();
            singleLinkedTestTemp.getHead().getNext().setNext(temp);
        }
        return singleLinkedTestTemp;
    }

    //获取倒数第K个节点
    public void getKNode(SingleLinkedTest singleLinkedTest,int k){
        int count = 0;
        HeroNode temp = singleLinkedTest.getHead(); //辅助节点
        if(temp.getNext() == null){
            System.out.println("链表为空,无法获取");
            return;
        }
        while (true){
            if (count == k){
                System.out.printf("倒数第%d个节点是:
"+temp,k);
                break;
            }
            temp = temp.getNext();
            count++;
        }
    }

    //展示链表所有数据
    public void showNode(SingleLinkedTest  singleLinkedTest){
        //定义辅助节点temp
        HeroNode temp = singleLinkedTest.getHead();
        if (temp.getNext() == null){
            System.out.println("当前链表为空~");
            return;
        }
        while (true){
            if (temp.getNext() == null){
                break;
            }
            System.out.println(temp.getNext());
            temp = temp.getNext();
        }
    }
}

4、开始测试

public class SingleLinked {
    public static void main(String[] args) {
        HeroNode heroNode1 = new HeroNode(1, "一号", "小明");
        HeroNode heroNode2 = new HeroNode(2, "二号", "小红");
        HeroNode heroNode3 = new HeroNode(3, "三号", "小君");
        HeroNode heroNode4 = new HeroNode(4, "四号", "小帅");
        HeroNode heroNode5 = new HeroNode(5, "五号", "小鹿");
        SingleLinkedTest singleLinkedTest = new SingleLinkedTest();
//        singleLinkedTest.addNode(heroNode1);//按照执行顺序添加节点
//        singleLinkedTest.addNode(heroNode2);
//        singleLinkedTest.addNode(heroNode3);
        singleLinkedTest.addOrderNode(heroNode1);//有序的添加节点
        singleLinkedTest.addOrderNode(heroNode5);
        singleLinkedTest.addOrderNode(heroNode4);
        singleLinkedTest.addOrderNode(heroNode3);
        singleLinkedTest.addOrderNode(heroNode2);
        singleLinkedTest.showNode(singleLinkedTest);//链表数据展示

        //求链表节点个数
        singleLinkedTest.getNodeCount();

        //求倒数第K个节点  + 链表反转 + 从尾到头打印
        SingleLinkedTest singleLinkedTestReversal =
                singleLinkedTest.reversalLink(singleLinkedTest);//得到反转后的链表
        singleLinkedTest.showNode(singleLinkedTestReversal);//展示反转后的链表数据
        singleLinkedTest.getKNode(singleLinkedTestReversal,5);//得到反转后的链表中第5条数据
    }
}

5、结果:

HeroNode[no=1,name=一号,nickname=小明]
HeroNode[no=2,name=二号,nickname=小红]
HeroNode[no=3,name=三号,nickname=小君]
HeroNode[no=4,name=四号,nickname=小帅]
HeroNode[no=5,name=五号,nickname=小鹿]
节点的个数为:5
HeroNode[no=5,name=五号,nickname=小鹿]
HeroNode[no=4,name=四号,nickname=小帅]
HeroNode[no=3,name=三号,nickname=小君]
HeroNode[no=2,name=二号,nickname=小红]
HeroNode[no=1,name=一号,nickname=小明]
倒数第5个节点是:
HeroNode[no=1,name=一号,nickname=小明]

一息若存,希望不灭
原文地址:https://www.cnblogs.com/yishuai/p/14438794.html