java 初识单链表

一、单链表是什么?

单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
java 初识单链表_第1张图片
现有一包糖果,班上共有三十六名同学,从第3个人数开始,每两个发两个糖果,问最后哪位同学没有糖果?请用程序计算出来。
创建NewBoy类,作为一个节点,next指向下一个节点

class NewBoy{
        private Integer no;

        private NewBoy next;

        public NewBoy(int no){
            this.no = no;
        }

        public Integer getNo() {
            return no;
        }

        public void setNo(Integer no) {
            this.no = no;
        }

        public NewBoy getNext() {
            return next;
        }

        public void setNext(NewBoy next) {
            this.next = next;
        }
}

编写主方法main,调用方法去实现

public static void main(String[] args) {
        //Todo 现有一包糖果,班上共有三十六名同学,从第3个人数开始,每两个发两个糖果,最后一名没有糖果,问最后哪位同学没有糖果?
        CircleSingleLinked c = new CircleSingleLinked();
        c.add(36);//创建单链表
        c.show();//遍历单链表
        c.countNewBoy(3,2,36);//计算哪位同学没有糖果
    }

方法实现

class CircleSingleLinked{

    NewBoy first = new NewBoy(-1);

        public void add(int num){
            //Todo  创建链表
            NewBoy curBoy = null;
            for (int i= 1;i<=num;i++){

                NewBoy boy = new NewBoy(i);
                //第一位同学将作为头结点
                if (i==1){
                    first = boy;
                    first.setNext(first);
                    curBoy = boy;
                }else{
                	//后面的同学走这边
                    curBoy.setNext(boy);
                    boy.setNext(first);
                    curBoy=boy;
                }
                System.out.printf("------->  第%d个小孩添加成功\n",i);
            }
        }

        public void show(){
            //Todo 遍历链表
            int i = 0;
            NewBoy newBoy = first;
            while (true){
                i++;
                System.out.printf("遍历现有同学------>  第%d同学\n",newBoy.getNo());
                if (newBoy.getNext()==first){
                    System.err.printf("共有%d个小孩\n",i);
                    break;
                }

                newBoy = newBoy.getNext();
            }
        }

    //根据用户的输入,计算出小孩节点出圈的顺序
    /*
    openNo表示从第几个同学开始数数
    share表示每几个发一次糖果
    sum表示最初有多少同学在圈
     */
    public void countNewBoy(int openNo,int share,int sum){
        //Todo 计算没有得到糖果的为第几位
        if (first == null || openNo < 1 || openNo > sum){
            System.out.println("参数输入有误,请重新输入!");
            return;
        }
        NewBoy newBoy = first;

        while (true){
            //遍历节点,事先指向最后节点
            if (newBoy.getNext() == first){
                break;
            }
            newBoy = newBoy.getNext();
        }
        //从第几个同学开始数数,将开始的同学提到第一位
        for (int i = 0;i<openNo-1;i++){
            first = first.getNext();
            newBoy = newBoy.getNext();
        }
        while (true){
            //圈中只剩一个节点,将得出谁没有得到糖果
            if (newBoy==first){
                System.err.printf("第%d位没有得到糖果\n",first.getNo());
                break;
            }
            //计算下一位得到糖果的同学
            for(int i = 0;i<share - 1;i++){
                first = first.getNext();
                newBoy = newBoy.getNext();
            }
            System.out.printf("第%d位同学得到糖果\n",first.getNo());
            //这时让得到糖果的同学出圈
            first = first.getNext();
            newBoy.setNext(first);
        }
    }
}

反转链表,用上面方法去调,有什么看不懂的欢迎来讨论

 //Todo 反转链表
    public void reverseList(){

        NewBoy boy = null;

        NewBoy newBoy = first;

        while (true){
            //遍历节点,事先指向最后节点
            if (newBoy.getNext() == first){
                break;
            }
            newBoy = newBoy.getNext();
        }

        while (newBoy!=null){

            NewBoy next = newBoy.getNext();

            newBoy.setNext(boy);

            boy = newBoy;
            newBoy = next;


        }
        first = boy;
        show();

    }

你可能感兴趣的:(数据结构)