数据结构-循环链表(三)(Java版)

 

目录

1,什么是循环链表

2,循环链表的实现

2.1,循环链表节点的定义

2.2,循环链表的实现

2.2.1,定义一个循环链表

2.2.2,向循环链表末尾添加一个元素

2.2.3,打印循环链表

2.2.4,根据元素值删除循环链表中的一个节点

2.2.5,约瑟夫环问题的实现

3,测试代码


1,什么是循环链表

循环链表是一种链式存储结构,它的最后一个结点指向头结点,形成一个环。因此,从循环链表中的任何一个结点出发都能找到任何其他结点。

  • 下面使用一张说明什么是循环链表:循环链表在逻辑上形成的是一个环,是单链表的一种改进,在单链表的基础上面,把最后一个节点的next域指向头结点,这样在逻辑上就可以形成一个环状的链表,从链表的任何一个节点开始,都可以访问到整个的链表元素。

2,循环链表的实现

2.1,循环链表节点的定义

class Cnode{
    private int data;
    public Cnode next;

    public Cnode(int data) {
        this.data = data;
    }

    public int getData() {
        return data;
    }

    @Override
    public String toString() {
        return "Cnode{" +
                "data=" + data +
                '}';
    }
}

2.2,循环链表的实现

2.2.1,定义一个循环链表

class CLinkedList{
    private Cnode head;//头指针
    private Cnode tail;//尾指针
    public CLinkedList(){
        head=new Cnode(-1);
        tail=new Cnode(-1);
        head.next=head;//形成一个环
        tail=head;//尾指针指向头
    }
 public Cnode getHead() {
        return head;
    }

    public Cnode getTail() {
        return tail;
    }
}

2.2.2,向循环链表末尾添加一个元素

 /**
     * 向循环链表中添加一个节点,添加在尾部
     * @param cnode 添加的节点
     * 链表的尾指针永远指向第一个元素(也就是头指针的下一个元素
     */
    public void addCnode(Cnode cnode){
        //说明此循环链表是空
        if(head.next == head){
            head.next=cnode;
            tail=cnode;
            tail.next=head.next;
        }else {
            //此循环链表不空
            tail.next=cnode;
            cnode.next=head.next;
            tail=cnode;
        }
    }

2.2.3,打印循环链表

//    打印循环链表
    void printCLinkedlist(){
        Cnode cnode=this.head.next;
        boolean flag=true;
        while (flag){
            System.out.print(cnode.getData()+" ");
            cnode=cnode.next;
            if(cnode.next== head.next){
                System.out.print(cnode.getData());
                flag=false;
            }
        }
    }

2.2.4,根据元素值删除循环链表中的一个节点

 /**
     * 根据元素的值,删除循环链表中的一个元素
     * @param value 要删除节点的值
     * @return 删除成功返回true,删除失败返回false
     */
    public boolean deleteValue(int value){
//        首先判断链表是否是空链表
        Cnode cnode=this.head;
//        链表空,删除不成功
        if(cnode.next == head)
            return false;
        Cnode cnode1=this.head.next;
        while (cnode1.next != head)
        {
//            找到需要删除的元素
            if(cnode1.getData() == value){
                cnode.next=cnode1.next;
                return true;
            }else {
                cnode=cnode.next;
                cnode1=cnode1.next;
            }
        }
          return false;

    }

2.2.5,约瑟夫环问题的实现

/**
     * m个人围成一个圈,指定一个数字n,从第一个人开始报数,每轮报到n的选手出局,
     * 由下一个人接着从头开始报,最后一个人是赢家。其中m>1,n>2。
     * @param cnode 循环链表的头结点
     * @param n 随机数字n,其中n>2
     */
    public static void JosephCircle(Cnode cnode,int n){
        Cnode cnode1=cnode.next;
        Cnode cnode2=cnode;
        int k=1;
        while (cnode1!= cnode2){
            while (k<=n-1){
                cnode1=cnode1.next;
                cnode2=cnode2.next;
                k++;
            }
//跳出循环,说明cnode1所指的节点要出队列
            System.out.println(cnode1.getData()+" ");
            cnode1=cnode1.next;
            cnode2.next=cnode1;
            k=1;
        }
        System.out.println(cnode1.getData()+" ");
    }

3,测试代码

public class ClinkedListDemo {
    public static void main(String[] args) {
        CLinkedList cLinkedList=new CLinkedList();
        cLinkedList.addCnode(new Cnode(1));
        cLinkedList.addCnode(new Cnode(2));
        cLinkedList.addCnode(new Cnode(3));
        cLinkedList.addCnode(new Cnode(4));
        cLinkedList.addCnode(new Cnode(5));
        cLinkedList.addCnode(new Cnode(6));
        cLinkedList.printCLinkedlist();
        System.out.println();
        //JosephCircle(cLinkedList.getHead(),2);
//        删除一个元素
        cLinkedList.deleteValue(3);
        cLinkedList.printCLinkedlist();
    }
  •  结果展示


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值