Java实现的循环单链表以及约瑟夫环的实现

定义Node结构体

用java实现Node的话最好用内部类的形式。

Node具体代码块

private class Node{
		E data;
		Node next;
		public Node() {
			this(null, null);
		}

		public Node(E data) {
			this(data, null);
		}

		public Node(E data, Node next) {
			this.data=data;
			this.next=next;
		}
	}

单向循环链表的实现

import 顺序表.List;

public class LinkedListSinglyCircular<E> implements List<E> {
	Node head;
	Node rear;
	int size;
	public LinkedListSinglyCircular() {
		head = new Node();
		head.next=head;
		rear = head;
		size = 0;
	}
	private class Node{
		E data;
		Node next;
		public Node() {
			this(null, null);
		}

		public Node(E data) {
			this(data, null);
		}

		public Node(E data, Node next) {
			this.data=data;
			this.next=next;
		}
	}
	@Override
	public int getSize() {
		// TODO Auto-generated method stub
		return size;
	}

	@Override
	public boolean isEmpty() {
		// TODO Auto-generated method stub
		return getSize()==0;
	}

	@Override
	public void add(int index, E e) {
		// TODO Auto-generated method stub
		if(index<0||index>size) {
			throw new IllegalArgumentException("下标越界");
		}
		//头插
		Node n=new Node(e);//存数据e
		if(index==0) {
			n.next=head.next;
			head.next=n;
			if(isEmpty()){//第一次添加元素 要更新尾指针
				rear=n;
				rear.next=rear;
			}else{
				rear.next=head.next;
			}
		}
		//尾插
		else if(index==size) {
			n.next=rear.next;
			rear.next=n;
			rear=n;
		}
		//中间任意插
		else {
			Node p=head;
			for(int i=0;i<index;i++) {
				p=p.next;
			}
			n.next=p.next;
			p.next=n;
		}
		
		size++;
	}

	@Override
	public void addFirst(E e) {
		// TODO Auto-generated method stub
		add(0, e);
	}

	@Override
	public void addLast(E e) {
		// TODO Auto-generated method stub
		add(size, e);
	}

	@Override
	public E get(int index) {
		// TODO Auto-generated method stub
		if(index<0||index>size-1) {
			throw new IllegalArgumentException("下表越界");
		}
		if(index>0) {
			index=index%size;
		}else {
			index=index%size+size;
		}
		Node p=head;
		for(int i=0;i<index;i++) {
			p=p.next;
		}
		return p.next.data;
	}

	@Override
	public E getFirst() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public E getLast() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void set(int index, E e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public boolean contains(E e) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public int find(E e) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public E remove(int index) {
		// TODO Auto-generated method stub
		if(index<0||index>size-1) {
			throw new IllegalArgumentException("下标越界");
		}
		E flag=null;
		if(index==0) {//头删
			Node p=head;
			flag=p.next.data;
			head.next=p.next.next;
			if(size==1) {
				rear=head;
				rear.next=rear;//必须保证rear有指向,无指向不构成循环,
			}
		}else if(index==size-1) {
			//尾删
			flag=rear.data;
			Node p=head;
			while(p.next!=rear) {
				p=p.next;
			}
			p.next=rear.next;
			rear=p;
		}
		else {
			//中间删除
			Node p=head;
			for(int i=0;i<index;i++) {
				p=p.next;
			}
			flag=p.next.data;
			p.next=p.next.next;
		}
		size--;
		return flag;
	}

	@Override
	public E removeFirst() {
		// TODO Auto-generated method stub
		
		return remove(0);
	}

	@Override
	public E removeLast() {
		// TODO Auto-generated method stub
		return remove(size-1);
	}

	@Override
	public void removeElement(E e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void clear() {
		// TODO Auto-generated method stub
		head=null;
		rear=head;
		size=0;
	}

	@Override
	public String toString() {
		StringBuilder sb=new StringBuilder();
		if(isEmpty()){
			return "[]";
		}else{
			sb.append("[");
			Node p=head;
			while(true){
				p=p.next;
				if(p==rear){
					sb.append(p.data+"]");
					break;
				}else{
					sb.append(p.data+",");
				}
			}
		}
		return sb.toString();
	}

	/*
	 * 约瑟夫环:
	 * 一伙人围成一圈而坐,从头开始数,第三个人自杀,然后从下一个人开始又开始数到
	 * 第三个人,这个人自杀,以此类推,求20个人中自杀的最终人是谁?
	 */
	public SingleLinkList<Integer> show(){
		SingleLinkList<Integer> l=new SingleLinkList<>();
		Node p=head;
		while(size>0) {
			p=p.next.next;
			Node n=p.next;	
			p.next=p.next.next;
			l.addLast((Integer)n.data);
			size--;//一定要减!!!!
		}
		return l;
	}
	
}

约瑟夫环

public SingleLinkList<Integer> show(){
		SingleLinkList<Integer> l=new SingleLinkList<>();
		Node p=head;
		while(size>0) {
			p=p.next.next;
			Node n=p.next;	
			p.next=p.next.next;
			l.addLast((Integer)n.data);
			size--;//一定要减!!!!
		}
		return l;
	}	

测试

package p02.动态链表;

public class TestlinklistCircular {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		LinkedListSinglyCircular<Integer> t=new LinkedListSinglyCircular<Integer>();
	    for(int i=39;i>=1;i--) {
	    	t.addFirst(i);
	    }
	     System.out.println(t);
	     System.out.println(t.show());
	}

}

测试结果

[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39]
[3,6,9,12,15,18,21,24,27,30,33,36,39,4,8,13,17,22,26,31,35,1,7,14,20,28,34,2,11,23,32,5,19,37,16,38,29,10,25]

上面为人的初始站位顺序,下面是自杀顺序。

猜你喜欢

转载自blog.csdn.net/qq_42405666/article/details/88898135