链表部分之循环单链表

循环单链表与单链表不同的是最后一个元素不为null,而是指向开头的第一个元素,形成一个环。
若temp=head,且没有头节点。
判满条件:temp.next=head
判空条件:head=null;
添加元素:若为第一个元素,head=newNode;head.next=head;//指向自己 temp=head;
若不是第一个元素:
temp.next=newNode; newNode.next=head; temp=newNode;
约瑟夫问题:简化说法,有K个小孩,编号为1,2,3,…,k,围成一个圈,现在假设让第n个小孩开始从1报数,需要报m次,数到m的那个小孩出列,下一个小孩重新从1开始报数,依次类推,直到所有的人都出列,问最后一个出列的小孩编号是多少?
代码如下:

package LinkedList;

public class Josefu     
{
	public static void main(String[] args) {
		ChildNode c1=new ChildNode(1);
		ChildNode c2=new ChildNode(2);
		ChildNode c3=new ChildNode(3);
		ChildNode c4=new ChildNode(4);
		ChildNode c5=new ChildNode(5);
		ChildNode c6=new ChildNode(6);
		CircleSingleLinkedList clist=new CircleSingleLinkedList();
		clist.add(5);
		clist.print();
		System.out.println("--------------");
		clist.rankNode(5, 1, 2);
	}
}
class CircleSingleLinkedList{
	//num数量 start开始位置 countnum数的数
	ChildNode head=new ChildNode(0);//没有头节点,只有头指针
	ChildNode last;//指向链表的最后一个元素
	//添加元素 辅助变量
	ChildNode cur=head;//遍历指针
	//添加
	public void add(int nums) {
		for(int i=1;i<=nums;i++) {
			ChildNode cnode=new ChildNode(i);
			if(i==1) {
				head=cnode;//第一个节点
				cnode.setNext(head);//指向自己
				cur=head;//保存当前节点
				continue;
			}
			cur.setNext(cnode);//该节点的下一个不再指向开头,指向下一个元素
			cnode.setNext(head);//下一个元素的指向开头
			cur=cnode;//右移
		}
		last=cur;
	}
	//显示
	public void print() {
		ChildNode helper=head;//辅助遍历
		while(true) {//开始等于最后
			System.out.println(helper.getCno());
			if(helper.getNext()==head) {
				break;
			}
			helper=helper.getNext();//不能将其写入在while中,会少一个右移
		}
	}
	
	//出圈顺序 先找到位置,再删掉
	public void rankNode(int nums,int start,int countnum) {
		if(head==null||start<1||start>nums) {
			System.out.println("输入无效");
			return;
		}
		
		// 找到开始位置 走了n-1步
		for (int i = 0; i < start - 1; i++) {
			last = last.getNext();// 右移
			head = head.getNext();
		}
		while(true) {
			if(last==head) {
				break;//走完了
			}
			
			//报数 报n-1步到
			
			for(int i=0;i<countnum-1;i++) {
				last=last.getNext();//指向要出队列的元素
				head=head.getNext();
			}
			
			System.out.println(head.getCno());
			head=head.getNext();//指针右移head=head.next
			last.setNext(head);//相当于last=first.next
		}
		System.out.println("最后出圈的人是"+last.getCno());
	}


}
//孩子节点类
class ChildNode
{
	ChildNode next;
	int cno;
	public ChildNode getNext() {
		return next;
	}
	public void setNext(ChildNode next) {
		this.next = next;
	}
	public int getCno() {
		return cno;
	}
	public void setCno(int cno) {
		this.cno = cno;
	}
	public ChildNode(int cno) {
		this.cno = cno;
	}
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值