链表(单链表,双向链表,单向环形链表)_java实现

25 篇文章 0 订阅

链表

单链表

在这里插入图片描述

在这里插入图片描述

  1. 不考虑排名,直接往最后一个位置插入元素

    package com.zhangan.linkedlist;
    
    public class SingleLinkedListDemo {
    
        public static void main(String[] args) {
    
            //创建节点
            HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
            HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
            HeroNode hero3 = new HeroNode(3, "吴用", "智多星");
            HeroNode hero4 = new HeroNode(4, "林冲", "豹子头");
    
    
            //创建链表
            SingleLinkedList singleLinkedList = new SingleLinkedList();
            singleLinkedList.add(hero1);
            singleLinkedList.add(hero2);
            singleLinkedList.add(hero3);
            singleLinkedList.add(hero4);
    
            //展示
            singleLinkedList.list();
    
        }
    }
    
    //定义一个SingleLinkedList  管理
    class SingleLinkedList {
    
        //初始化一个头节点
        private HeroNode head = new HeroNode(0, "", "");
    
        //添加节点到单向链表
        //1。找到当前链表的最后节点
        //2。将最后这个节点的next指向新的节点
        public void add(HeroNode heroNode) {
    
            //头节点不能动  需要一个辅助变量来遍历链表
            HeroNode temp = head;
            //遍历链表,找到最后
            while (true) {
                //找到了最后一个节点
                if (temp.next == null) {
                    break;
                }
                //如果不是最后一个节点  temp后移
                temp = temp.next;
            }
            //循环结束,temp指向链表最后
            temp.next = heroNode;
        }
    
    
        //展示链表
        public void list() {
            //判断链表是否为空
            if (head.next == null) {
                System.out.println("空链表,无值");
                return;
            }
            //使用变量遍历
            HeroNode temp = head.next;
            while (true) {
                if (temp == null) {
                    break;
                }
    
                System.out.println(temp.toString());
                temp = temp.next;
            }
        }
    }
    
    
    //定义一个节点
    class HeroNode {
    
        public int no;
        public String name;
        public String nickname;
        public HeroNode next; //next域 指向下一个节点
    
        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 +
                    '}';
        }
    }
    
  2. 根据排名添加

     //根据英雄的排名  添加到指定位置
        public void addByOrder(HeroNode heroNode) {
            //辅助变量来找合适的添加的位置
            HeroNode temp = head;
    
            boolean flag = false;//添加的编号是否存在
            while (true) {
    
                if (temp.next == null) {//说明temp在链表最后
                    break;
                }
                if (temp.next.no > heroNode.no) {//位置找到了 就在temp之后
                    break;
                } else if (temp.next.no == heroNode.no) {
                    flag = true;//编号已存在
                    break;
                }
    
                temp = temp.next;//后移
            }
    
            if (flag) {
                System.out.println("准备插入的英雄编号已经存在了");
            } else {
                //插入链表  temp的后面
                heroNode.next = temp.next;
                temp.next = heroNode;
    
            }
    
        }
    
  3. 根据编号修改

        //修改节点的信息  根据编号no来修改
        public void update(HeroNode newHeroNode) {
            //判断链表是否为空
            if (head.next == null) {
                System.out.println("空链表,无值");
                return;
            }
            HeroNode temp = head.next;
            boolean flag = false;//表示是否找到节点
            while (true) {
                if (temp == null) {
                    break;
                }
                if (temp.no == newHeroNode.no) {
                    flag = true;
                    break;
                }
                temp = temp.next;
    
            }
            if (flag) {
                temp.name = newHeroNode.name;
                temp.nickname = newHeroNode.nickname;
    
    
            } else {
                System.out.println("没有该英雄");
            }
    
        }
    
  4. 删除指定节点

        //删除指定节点
        public void delete(Integer id) {
            //判断链表是否为空
            if (head.next == null) {
                System.out.println("空链表,无值");
                return;
            }
            HeroNode temp = head;
            boolean flag = false;//是否找到要删除的节点
            while (true) {
                if (temp.next == null) {
                    break;
                }
                if (temp.next.no == id) {
                    flag = true;
                    break;
                }
                temp = temp.next;
            }
    
            if (flag) {
                temp.next = temp.next.next;
    
            } else {
                System.out.println("没有该英雄");
            }
        }
    
双向链表

在这里插入图片描述

代码实现:

package com.zhangan.linkedlist;


//创建双向链表的节点
class Node {

    public int no;
    public String name;
    public String nickname;
    public Node next;//指向下一个节点
    public Node pre;//指向前一个结点

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

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


class DoubleLinkedList {

    //初始化 头节点
    private Node head = new Node(0, "", "");

    public Node getHead() {
        return head;
    }

    //判断链表是否为空
    public boolean isEmpty() {
        return head.next == null;
    }

    //遍历链表
    public void list() {

        if (isEmpty()) {
            System.out.println("链表为空");
            return;
        }
        Node temp = head.next;
        while (temp != null) {
            System.out.println(temp.toString());
            temp = temp.next;
        }
    }

    //添加节点
    public void add(Node node) {
        Node temp = head;

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

    }

    //修改节点
    public void update(Node node) {
        if (isEmpty()) {
            System.out.println("链表为空");
            return;
        }

        Node temp = head.next;
        boolean flag = false;
        while (temp != null) {

            if (temp.no == node.no) {
                flag = true;
                break;
            }

            temp = temp.next;
        }
        if (flag) {
            temp.name = node.name;
            temp.nickname = node.nickname;
        } else {
            System.out.println("没有该数据");
        }
    }

    //删除节点
    public void delete(Integer id) {

        if (isEmpty()) {
            System.out.println("链表为空");
            return;
        }

        Node temp = head.next;
        boolean flag = false;//是否找到要删除的节点
        while (temp != null) {

            if (temp.no == id) {
                flag = true;
                break;
            }

            temp = temp.next;
        }

        if (flag) {
            temp.pre.next = temp.next;
            if (temp.next != null) {//防止删除的是最后一个节点

                temp.next.pre = temp.pre;
            }

        } else {
            System.out.println("没有该数据");
        }

    }

    //按编号添加
    public void addByOrder(Node node) {

        Node temp = head;
        boolean flag = false;//添加的编号是否存在
        while (temp.next != null) {

            if (temp.next.no > node.no) {
                break;
            }
            if (temp.next.no == node.no) {
                flag = true;
                break;
            }

            temp = temp.next;
        }
        if (flag) {
            System.out.println("该编号存在:" + node.no);

        } else {
            node.next = temp.next;
            temp.next = node;
            node.pre = temp;
        }

    }
}

public class DoubleLinkedListDemo {


    public static void main(String[] args) {

        DoubleLinkedList doubleLinkedList = new DoubleLinkedList();

        Node node1 = new Node(1, "name1", "111");
        Node node2 = new Node(2, "name2", "222");
        Node node3 = new Node(3, "name3", "333");
        Node node4 = new Node(4, "name4", "444");
        Node node5 = new Node(5, "name5", "555");

        doubleLinkedList.addByOrder(node5);
        doubleLinkedList.addByOrder(node4);
        doubleLinkedList.addByOrder(node3);
        doubleLinkedList.addByOrder(node2);
        doubleLinkedList.addByOrder(node1);

        doubleLinkedList.list();
        System.out.println("---------------------------");

        //测试修改
//        Node node5update = new Node(5, "name5修改", "555修改");
//        doubleLinkedList.update(node5update);
//        doubleLinkedList.list();

        //测试删除
//        doubleLinkedList.delete(2);
//        doubleLinkedList.list();

    }

}

单向环形链表

在这里插入图片描述

构建一个单向的环形链表思路

1.先创建第一个节点,让first指向该节点,并形成环形

2.后面当我们每创建一个新的节点,就把该节点,加入到已有的环形链表中即可.

遍历环形链表

1.先让一个铺助指针(变量) curBoy,指向first节点

2然后通过一个while循环遍历该环形链表即可curBoy.next == first结束

出圈思路:

1.需求创建一个辅助指针 helper ,事先应该指向环形链表的最后这个节点.
2.当小孩报数时,i让first和helper指针同时的移动m -1次

3.这时就可以将first指向的小孩节点出圈
first = first. Next
helper.next =first
原来first指向的节点就没有任何引用,就会被回收

代码部分:

package com.zhangan.linkedlist;

//创建一个boy  表示一个节点
class Boy {
    private int no;
    private Boy next;

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

    @Override
    public String toString() {
        return "Boy{" +
                "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;
    }
}

//单向环形链表
class CircleSingleLinkedList {

    //创建一个first 节点
    private Boy first = null;

    //添加小孩节点  构建成环形链表
    public void addBoy(int nums) {
        if (nums < 1) {
            System.out.println("nums值不正确");
            return;
        }

        Boy curBoy = null;//辅助指针  帮助构建环形链表
        for (int i = 1; i <= nums; i++) {

            Boy boy = new Boy(i);

            //如果是第一个小孩
            if (i == 1) {
                first = boy;

                first.setNext(first);
                curBoy = first; //curBoy指向第一个小孩
            } else {
                curBoy.setNext(boy);
                boy.setNext(first);
                curBoy = boy;
            }
        }
    }

    //遍历当前环形链表
    public void list() {

        if (first == null) {
            System.out.println("链表为空");
            return;
        }

        Boy curBoy = first;
        while (true) {
            System.out.println("小孩的编号:" + curBoy.getNo());

            if (curBoy.getNext() == first) {//已经遍历完成
                break;
            }
            curBoy = curBoy.getNext();
        }


    }


    //根据用户输入 计算小孩出圈的顺序
    /**
     * @param startNo  第几个小孩开始数数
     * @param countNum 数几下
     * @param nums     共有多少小孩
     */
    public void outBoy(int startNo, int countNum, int nums) {

        if (first == null || startNo < 1 || startNo > nums) {
            System.out.println("参数有误");
            return;
        }

        Boy helper = first;
        while (true) {
            if (helper.getNext() == first) {//说明helper指向最后一个小孩节点
                break;
            }
            helper = helper.getNext();
        }

        //第几个小孩报数 first移动到该小孩 helper紧随其后
        for (int i = 0; i < startNo - 1; i++) {
            first = first.getNext();
            helper = helper.getNext();
        }

        //当小孩报数时,让first和helper指针同时的移动countNum-1次,然后出圈
        while (true) {
            if (helper == first) {//圈里只有一个人了
                break;
            }

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

            //此时first指向的节点就是要出圈的小孩
            System.out.println("小孩" + first.getNo() + "出圈");

            first = first.getNext();
            helper.setNext(first);
        }

        System.out.println("最后留在圈中的小孩是" + first.getNo());

    }


}


public class Josephus {

    public static void main(String[] args) {


        CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();

        circleSingleLinkedList.addBoy(5);
        circleSingleLinkedList.list();
        System.out.println("-------------------------------");


        circleSingleLinkedList.outBoy(1,2,5);
    }


}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值