1. 之所以做这样一个问题是源于书后的一道应用题。下面对这个题目做下说明:
循环链表是一种链表,它的最后一个链结点指向第一个链结点。设计循环链表有许多方法,有时,用一个指向链表“开始”的指针,然而这样做使得链表不像一个环,而更像传统的链表,只不过这个链表的表头和表尾连在了一起。编写一个类代表循环单链表,它没有表头也没有表尾。访问这个链表的唯一方式是一个引用current,它能指向链表上的任何结点,这个引用可以沿链表移动。你的链表应该能够插入、查找和删除。
开始编写的时候遇到一些问题,主要是如果只使用引用current,发现无法形成一个环形链表,因为无法找个一个连接处。所以后来添加了一个link对象只用于保持一个入口用于形成循环链表。具体的操作如图示:
2.实现代码如下:
- package linklist;
- public class Link {
- public double dData; //data item
- public Link next; //next link in list
- //.....................................................
- public Link(double dd)
- {
- dData=dd;
- }
- //.....................................................
- public void displayLink()
- {
- System.out.print("{"+dData+"}");
- }
- }//end class Link
- package linklist;
- //循环链表类
- public class RecycleLinkList {
- private Link current; //指向的当前节点
- private int itemNum=0; //当前循环链表内的节点数目
- public int TotalNum; //循环链表的最大节点数
- public Link start; //用于标记节点起始点
- //.....................................................
- public RecycleLinkList(int t)
- {
- current=null; //no item yet
- TotalNum=t;//总数目
- }
- //.....................................................
- public boolean isEmpty() //true if list is empty
- {
- return (current==null);
- }
- //.....................................................
- public void insertCurrent(double dd)//insert link into linklist
- {
- Link newLink=new Link(dd); //new link
- if(isEmpty())start=newLink; //start ref to the first link in the linklist
- newLink.next=current; //newlink-->old current
- current=newLink; //first==current
- itemNum++; //added new items
- if(itemNum>=TotalNum) //if the link is full,start-->current(the last link)
- {
- start.next=current;
- current=start;
- }
- }
- //.....................................................
- public Link delete() //delete link which ref to current.next
- {
- Link CurrentNext=current.next;//
- current.next=current.next.next;//current-->current.next.next
- current=current.next;
- itemNum--;
- TotalNum--;
- return CurrentNext;
- }
- //..............................................................
- public Link find(double key)
- {
- int counter=0;
- while(current.dData!=key)
- {
- counter++;
- if(counter>TotalNum) //
- return null;
- else
- current=current.next;
- }
- return current;
- }
- //.....................................................
- public void displayList()
- {
- System.out.print("List(first-->last):");
- int counter=0;
- Link a=current;
- while(a!=null)
- {
- counter++;
- if(counter>TotalNum)
- {
- System.out.println("");
- break;
- }
- else
- a.next.displayLink();
- a=a.next;
- }
- System.out.println("");
- }
- // ........................................................
- public void step()
- {
- current=current.next;
- }
- // ........................................................
- }
3.约瑟夫环Josephus问题
Josephus环问题是古代的一个数学难题,Josephus是为罗马人抓到的一群犹太人中的一个,为了避免被奴役,他们决定自杀,Josephus不想自杀,于是他提出了规则,一群人围成一个圈,从某人开始,沿着圆圈计数,每报到第N个数的人就要离开圈圈去自杀。Josephus通过制定的规则使自己成了最后一个离开圆圈的人。如果有20个人,而他是第7个人,那么如果制定规则才能幸存呢?这个问题会越来越复杂,因为随着人的减少,圈也变得越来越小。
应用之上的循环单链表类,可以模拟这样一个过程,输入为总人数,起始编号以及报数。
代码如下:
- package linklist;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import Stack.InToPost;
- public class RecycleLinkListApps {
- /**
- * @param args
- * @throws IOException
- */
- public static void main(String[] args) throws IOException {
- // TODO Auto-generated method stub
- //
- // RecycleLinkList theList=new RecycleLinkList(7);
- // theList.insertCurrent(3.99);
- // theList.insertCurrent(4.99);
- // theList.insertCurrent(5.99);
- // theList.insertCurrent(6.99);
- // theList.insertCurrent(7.99);
- // theList.insertCurrent(8.99);
- // theList.insertCurrent(9.99);
- // theList.delete();
- // theList.displayList();
- int input;
- int i;
- while(true)
- {
- System.out.print("Enter the total number of the people: ");
- System.out.flush();
- input=Integer.parseInt(getString());
- RecycleLinkList theList=new RecycleLinkList(input);
- for(i=0;i<input;i++) //插入赋值
- {
- theList.insertCurrent(i+1);
- }
- System.out.print("Enter the start number of the Joseph circle : ");//输入起始编号
- input=Integer.parseInt(getString());
- for(i=0;i<input;i++)theList.step();
- System.out.print("Enter the number we call: "); //输入间隔数目
- input=Integer.parseInt(getString());
- while(theList.TotalNum>1)
- {
- for(i=0;i<input-2;i++)
- {
- theList.step();
- }
- theList.delete();
- theList.displayList();
- }
- //System.out.println("Postfix is: "+output+'/n');
- }//end while
- }//end main
- //...........................................................
- public static String getString()throws IOException
- {
- InputStreamReader in=new InputStreamReader(System.in);
- BufferedReader br=new BufferedReader(in);
- String s=br.readLine();
- return s;
- }
- }
模拟结果如下:
- Enter the total number of the people: 7
- Enter the start number of the Joseph circle : 1
- Enter the number we call: 4
- List(first-->last):{2.0}{1.0}{7.0}{6.0}{5.0}{3.0}
- List(first-->last):{5.0}{3.0}{2.0}{1.0}{6.0}
- List(first-->last):{6.0}{5.0}{3.0}{1.0}
- List(first-->last):{6.0}{5.0}{1.0}
- List(first-->last):{5.0}{6.0}
- List(first-->last):{6.0}
- Enter the total number of the people: