第四章、链表(单链表、双链表、约瑟夫问题)

单链表

节点定义

public class HeroNode {
    public int no; //序号
    public String name;
    public String nickName;
    public HeroNode next;

    public HeroNode(int no, String name, String nickName, HeroNode next) {
        this.no = no;
        this.name = name;
        this.nickName = nickName;
        this.next = next;
    }

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

单链表

public class SingleLinkedList {
    private HeroNode head = new HeroNode(0, "", "", null);

    public HeroNode getHead() {
        return head;
    }

    //添加元素
    public void add(HeroNode heroNode){
        HeroNode temp = head;

        while (temp.next != null){
            temp = temp.next;
        }

        temp.next = heroNode;
    }

    //显示元素
    public void show(){
        if (head.next == null){
            System.out.println("单链表为空");
        }

        HeroNode temp = head.next;
        while (temp != null){
            System.out.println(temp);
            temp = temp.next;
        }
    }

    //按照顺序添加元素
    public void addByOrder(HeroNode heroNode){
        HeroNode temp = head;
        while (temp.next != null){
            if (temp.next.no > heroNode.no){
                break;
            } else if (temp.next.no == heroNode.no) {
                System.out.println("编号" + heroNode.no + "已经存在,添加失败");
                return;
            }

            temp = temp.next;
        }

        heroNode.next = temp.next;
        temp.next = heroNode;
    }

    //根据编号no修改单链表中的元素
    public void update(HeroNode heroNode){
        HeroNode temp = head.next;
        if (temp == null){
            System.out.println("单链表为空,修改失败");
            return;
        }

        while (temp != null){
            if (temp.no == heroNode.no)
                break;
            else
                temp = temp.next;
        }
        if (temp == null) {
            System.out.println("没有找到编号为:" + heroNode.no + "的元素");
            return;
        }
        else{
            temp.name = heroNode.name;
            temp.nickName = heroNode.nickName;
        }
    }

    //删除节点
    public void delete(HeroNode heroNode){
        HeroNode temp = head;
        if (temp.next == null){
            System.out.println("单链表为空,删除失败");
            return;
        }

        while (temp.next != null){
            if (temp.next.no == heroNode.no)
                break;
            else
                temp = temp.next;
        }

        if (temp.next == null){
            System.out.println("没找到编号为:" + heroNode.no + "的元素,删除失败");
            return;
        }else
            temp.next = temp.next.next;
    }
}

测试类

public class Test {
    public static void main(String[] args) {
        //创立单链表
        SingleLinkedList singleLinkedList = new SingleLinkedList();

        HeroNode hero1 = new HeroNode(1, "宋江", "及时雨", null);
        HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟", null);
        HeroNode hero3 = new HeroNode(3, "吴用", "智多星", null);
        HeroNode hero4 = new HeroNode(4, "林冲", "豹子头", null);

        //添加节点
//        singleLinkedList.add(hero1);
//        singleLinkedList.add(hero2);
//        singleLinkedList.add(hero3);
//        singleLinkedList.add(hero4);

        singleLinkedList.addByOrder(hero1);
        singleLinkedList.addByOrder(hero4);
        singleLinkedList.addByOrder(hero3);
        singleLinkedList.addByOrder(hero2);

        singleLinkedList.show();
        System.out.println();

        //删除节点
        //HeroNode newhero = new HeroNode(2, "小卢", "玉麒麟。。", null);
        //singleLinkedList.update(newhero);
        HeroNode newhero = new HeroNode(2, "卢俊义", "玉麒麟", null);
        singleLinkedList.delete(newhero);


        singleLinkedList.show();

        //查找元素个数
        System.out.println();
        System.out.println("单链表的节点个数 = " + getlenth(singleLinkedList.getHead()));

        //查找倒数第k个元素
        System.out.println();
        int Index = 4;
        HeroNode indexNode = findLastIndexNode(singleLinkedList.getHead(), Index);
        System.out.println(indexNode);
        if (indexNode == null)
            System.out.println("没有找到倒数第:" + Index + "个元素");
        else {
            System.out.println("倒数第:" + Index + "个元素为:");
            System.out.println(indexNode);
        }

        //反转单链表
        System.out.println();
        reverse(singleLinkedList.getHead());
        singleLinkedList.show();

        //逆序打印
        System.out.println();
        reversePrint(singleLinkedList.getHead());

        //合并两个单链表
        System.out.println();
        SingleLinkedList s1 = new SingleLinkedList();
        HeroNode h1 = new HeroNode(1, "孙悟空", "小孙", null);
        HeroNode h3 = new HeroNode(3, "猪八戒", "小猪", null);
        s1.addByOrder(h1);
        s1.addByOrder(h3);

        System.out.println();
        SingleLinkedList s2 = new SingleLinkedList();
        HeroNode h2 = new HeroNode(2, "唐僧", "小唐", null);
        HeroNode h4 = new HeroNode(4, "沙悟净", "小沙", null);
        s2.addByOrder(h2);
        s2.addByOrder(h4);

        merge(s1.getHead(), s2.getHead());
        s1.show();

    }

    //合并两个有序的单链表,合并后仍然有序
    public static void merge(HeroNode head1, HeroNode head2){
        HeroNode head3 = new HeroNode(0, "", "", null);
        HeroNode temp1 = head1.next;
        HeroNode temp2 = head2.next;
        HeroNode temp3 = head3;

        while (temp1 != null && temp2 != null){
            if (temp1.no <= temp2.no){
                head1.next = temp1.next;
                temp3.next = temp1;
                temp3 = temp1;
                temp1 = head1.next;
            }else {
                head2.next = temp2.next;
                temp3.next = temp2;
                temp3 = temp2;
                temp2 = head2.next;
            }
        }

        if (temp1 != null)
            temp3.next = temp1;

        if (temp2 != null)
            temp3.next = temp2;

        head1.next = head3.next;
    }

    //实现逆序打印
    public static void reversePrint(HeroNode head){
        if (head == null){
            System.out.println("单链表为空,不能打印");
            return;
        }

        Stack<HeroNode> stack = new Stack<>();
        HeroNode temp = head.next;
        while (temp != null){
            stack.push(temp);
            temp = temp.next;
        }

        while (stack.size() > 0)
            System.out.println(stack.pop());
    }


    //单链表的反转
    public static void reverse(HeroNode head){
        if (head.next == null || head.next.next == null)
            return;

        HeroNode reverseHead = new HeroNode(0, "", "", null);
        HeroNode temp = head.next;
        while (temp != null){
            head.next = temp.next;
            temp.next = reverseHead.next;
            reverseHead.next = temp;
            temp = head.next;
        }

        head.next = reverseHead.next;
    }

    /**
     * 方法:查找倒数第k个节点
     * @param head 头结点
     * @param Index 倒数第Index个节点的索引
     * @return
     */
    public static HeroNode findLastIndexNode(HeroNode head, int Index){
        int num = getlenth(head);
        if (num < Index)
            return null;
        HeroNode temp = head.next;
        for (int i = 0; i < (num - Index); i++) {
            temp = temp.next;
        }
        return temp;
    }

    /**
     * 方法:求单链表中元素个数
     * @param head 头结点
     * @return
     */
    public static int getlenth(HeroNode head){
        if (head.next == null)
            return 0;

        HeroNode temp = head.next;
        int length = 0;
        while (temp != null){
            length++;
            temp = temp.next;
        }
        return length;
    }
}

双链表

节点定义

public class HeroNode {
    public int no; //序号
    public String name;
    public String nickName;
    public HeroNode next;
    public HeroNode pre;

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

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

双链表

public class DoubleLinkedList {
    private HeroNode head = new HeroNode(0, "", "");

    public HeroNode getHead() {
        return head;
    }

    //按照编号添加元素
    public void addByNo(HeroNode heroNode) {
        HeroNode temp = head;
        while (temp.next != null) {
            if (temp.next.no > heroNode.no) {
                break;
            } else if (temp.next.no == heroNode.no) {
                System.out.println("编号" + heroNode.no + "已经存在,添加失败");
                return;
            }

            temp = temp.next;
        }

        heroNode.next = temp.next;
        if (temp.next != null)
            temp.next.pre = heroNode;
        heroNode.pre = temp;
        temp.next = heroNode;
    }

    //删除元素
    public void delete(HeroNode heroNode) {
        HeroNode temp = head.next;
        if (temp == null) {
            System.out.println("双链表为空,删除失败");
            return;
        }

        while (temp != null) {
            if (temp.no == heroNode.no)
                break;
            else
                temp = temp.next;
        }

        if (temp == null) {
            System.out.println("没找到编号为:" + heroNode.no + "的元素,删除失败");
            return;
        } else {
            temp.pre.next = temp.next;
            if (temp.next != null)
                temp.next.pre = temp.pre;
        }
    }

    //修改元素
    public void update(HeroNode heroNode) {
        HeroNode temp = head.next;
        if (temp == null) {
            System.out.println("双链表为空,修改失败");
            return;
        }

        while (temp != null) {
            if (temp.no == heroNode.no)
                break;
            else
                temp = temp.next;
        }
        if (temp == null) {
            System.out.println("没有找到编号为:" + heroNode.no + "的元素");
            return;
        } else {
            temp.name = heroNode.name;
            temp.nickName = heroNode.nickName;
        }
    }

    //在链表末尾添加元素
    public void add(HeroNode heroNode) {
        HeroNode temp = head;

        while (temp.next != null) {
            temp = temp.next;
        }

        temp.next = heroNode;
        heroNode.pre = temp;
    }

    //遍历
    public void show() {
        if (head.next == null) {
            System.out.println("双链表为空");
        }

        HeroNode temp = head.next;
        while (temp != null) {
            System.out.println(temp);
            temp = temp.next;
        }
    }
}

测试类

public class Test {
    public static void main(String[] args) {
        //创立单链表
        DoubleLinkedList doubleLinkedList = new DoubleLinkedList();

        HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
        HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
        HeroNode hero3 = new HeroNode(3, "吴用", "智多星");
        HeroNode hero5 = new HeroNode(5, "林冲", "豹子头");

        //添加节点
        doubleLinkedList.add(hero1);
        doubleLinkedList.add(hero2);
        doubleLinkedList.add(hero3);
        doubleLinkedList.add(hero5);
        doubleLinkedList.show();

        //修改节点
//        System.out.println();
//        HeroNode newhero = new HeroNode(2, "小卢", "玉麒麟。。");
//        doubleLinkedList.update(newhero);
//        doubleLinkedList.show();

        //删除节点
//        System.out.println();
//        HeroNode newhero = new HeroNode(2, "卢俊义", "玉麒麟");
//        doubleLinkedList.delete(newhero);
//        doubleLinkedList.show();

        //按照编号添加元素
        System.out.println();
        HeroNode hero4 = new HeroNode(4, "沙悟净", "小沙");
        HeroNode hero6 = new HeroNode(6, "哪吒", "小喳");
        doubleLinkedList.addByNo(hero4);
        doubleLinkedList.addByNo(hero6);
        doubleLinkedList.show();


    }
}

约瑟夫问题(循环单链表)

  • 设编号为1, 2, …n的n个人围坐一圈,num个人从编号startNum开始报数,数到countNum的那个人出列,他的下一位又从1开始报数,数到countNum的那个人又出列,一次类推,知道所有人出列为止,由此产生一个出队编号的序列

小孩类

public class Boy {
    private int no;
    private Boy next;

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

    public int getNo() {
        return no;
    }

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

    public Boy getNext() {
        return next;
    }

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

循环单链表

public class CircleSingleLinkedList {
    private Boy first = null;

    /**
     *
     * @param startNo 开始的小孩的编号
     * @param countNum 每次跳过的次数
     * @param num 最初的小孩数目
     */
    //出圈
    public void countBoy(int startNo, int countNum, int num){
        if (first == null || startNo < 1 || startNo > num){
            System.out.println("数据不合理,请重新输入");
            return;
        }

        Boy temp = first;
        while (temp.getNext() != first)
            temp = temp.getNext();

        for (int i = 0; i < startNo - 1; i++) {
            first = first.getNext();
            temp = temp.getNext();
        }

        while (temp != first){
            for (int i = 0; i < countNum - 1; i++) {
                first = first.getNext();
                temp = temp.getNext();
            }

            System.out.println("小孩:" + first.getNo() + "出圈");
            first = first.getNext();
            temp.setNext(first);
        }

        System.out.println("小孩:" + first.getNo() + "获得胜利");
    }

    //添加节点
    public void addBoy(int num){
        if (num < 1){
            System.out.println("num数据不合理");
            return;
        }

        Boy temp = new Boy(0);
        for (int i = 1; i <= num; i++) {
            Boy boy = new Boy(i);
            if (i == 1){
                first = boy;
                first.setNext(first);
                temp = first;
            }else{
                temp.setNext(boy);
                boy.setNext(first);
                temp = boy;
            }
        }
    }

    //遍历链表
    public void show(){
        if (first == null)
            System.out.println("链表为空");

        Boy temp = first;
        while (true){
            System.out.println("小孩编号为:" + temp.getNo());
            if (temp.getNext() == first)
                break;
            temp = temp.getNext();
        }
    }
}

测试类

public class test {
    public static void main(String[] args) {
        CircleSingleLinkedList c = new CircleSingleLinkedList();
        c.addBoy(5);
        c.show();

        c.countBoy(1, 2, 5);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值