基于java的数据结构学习手记8--循环单链表及其应用约瑟夫环

   1.     之所以做这样一个问题是源于书后的一道应用题。下面对这个题目做下说明:

        循环链表是一种链表,它的最后一个链结点指向第一个链结点。设计循环链表有许多方法,有时,用一个指向链表“开始”的指针,然而这样做使得链表不像一个环,而更像传统的链表,只不过这个链表的表头和表尾连在了一起。编写一个类代表循环单链表,它没有表头也没有表尾。访问这个链表的唯一方式是一个引用current,它能指向链表上的任何结点,这个引用可以沿链表移动。你的链表应该能够插入、查找和删除。

         开始编写的时候遇到一些问题,主要是如果只使用引用current,发现无法形成一个环形链表,因为无法找个一个连接处。所以后来添加了一个link对象只用于保持一个入口用于形成循环链表。具体的操作如图示:

        

     

2.实现代码如下:

          

Code:
  1. package linklist;  
  2.   
  3. public class Link {  
  4.     public double dData;    //data item  
  5.     public Link next;      //next link in list  
  6. //.....................................................  
  7.     public Link(double dd)  
  8.     {  
  9.       
  10.         dData=dd;     
  11.     }  
  12. //.....................................................   
  13. public void displayLink()  
  14. {  
  15.     System.out.print("{"+dData+"}");      
  16. }  
  17. }//end class Link  
Code:
  1. package linklist;  
  2. //循环链表类  
  3. public class RecycleLinkList {  
  4.     private Link current;     //指向的当前节点  
  5.     private int itemNum=0;   //当前循环链表内的节点数目  
  6.     public int TotalNum;     //循环链表的最大节点数  
  7.     public Link start;       //用于标记节点起始点  
  8.       
  9.     //.....................................................  
  10.        public RecycleLinkList(int t)  
  11.         {  
  12.             current=null;  //no item yet  
  13.             TotalNum=t;//总数目  
  14.               
  15.         }  
  16.     //.....................................................  
  17.         public boolean isEmpty()  //true if list is empty  
  18.         {  
  19.             return (current==null);  
  20.         }  
  21.     //.....................................................    
  22.         public void insertCurrent(double dd)//insert link into linklist  
  23.         {     
  24.             Link newLink=new Link(dd);      //new link  
  25.             if(isEmpty())start=newLink;     //start ref to the first link in the linklist  
  26.               
  27.               newLink.next=current;  //newlink-->old current  
  28.               current=newLink;       //first==current  
  29.               itemNum++;             //added new items  
  30.             if(itemNum>=TotalNum)    //if the link is full,start-->current(the last link)  
  31.                 {  
  32.                 start.next=current;  
  33.                 current=start;  
  34.                 }  
  35.         }  
  36.     //.....................................................  
  37.         public Link delete()            //delete link which ref to current.next  
  38.         {     
  39.                 Link CurrentNext=current.next;//  
  40.                 current.next=current.next.next;//current-->current.next.next  
  41.                 current=current.next;            
  42.                 itemNum--;  
  43.                 TotalNum--;  
  44.                 return CurrentNext;  
  45.         }  
  46.     //..............................................................  
  47.         public Link find(double key)  
  48.         {  
  49.             int counter=0;  
  50.             while(current.dData!=key)  
  51.             {       
  52.                 counter++;  
  53.             if(counter>TotalNum)    //  
  54.                        return null;  
  55.             else  
  56.                 current=current.next;     
  57.             }  
  58.            return current;  
  59.         }  
  60.     //.....................................................  
  61.          public void displayList()  
  62.          {  
  63.              System.out.print("List(first-->last):");  
  64.              int counter=0;  
  65.              Link a=current;  
  66.              while(a!=null)  
  67.              {    
  68.                  counter++;  
  69.        
  70.                 if(counter>TotalNum)  
  71.                     {  
  72.                     System.out.println("");  
  73.                     break;  
  74.                     }  
  75.                 else   
  76.                  a.next.displayLink();  
  77.                  a=a.next;  
  78.                    
  79.              }  
  80.              System.out.println("");  
  81.          }  
  82.     // ........................................................  
  83.          public void step()  
  84.          {  
  85.              current=current.next;  
  86.          }  
  87.            
  88.     // ........................................................  
  89.   
  90.   
  91. }  

3.约瑟夫环Josephus问题

      Josephus环问题是古代的一个数学难题,Josephus是为罗马人抓到的一群犹太人中的一个,为了避免被奴役,他们决定自杀,Josephus不想自杀,于是他提出了规则,一群人围成一个圈,从某人开始,沿着圆圈计数,每报到第N个数的人就要离开圈圈去自杀。Josephus通过制定的规则使自己成了最后一个离开圆圈的人。如果有20个人,而他是第7个人,那么如果制定规则才能幸存呢?这个问题会越来越复杂,因为随着人的减少,圈也变得越来越小。

      应用之上的循环单链表类,可以模拟这样一个过程,输入为总人数,起始编号以及报数。

代码如下:

Code:
  1. package linklist;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStreamReader;  
  6.   
  7. import Stack.InToPost;  
  8.   
  9. public class RecycleLinkListApps {  
  10.   
  11.     /** 
  12.      * @param args 
  13.      * @throws IOException  
  14.      */  
  15.     public static void main(String[] args) throws IOException {  
  16.         // TODO Auto-generated method stub  
  17. //        
  18. //      RecycleLinkList theList=new RecycleLinkList(7);  
  19. //      theList.insertCurrent(3.99);  
  20. //      theList.insertCurrent(4.99);  
  21. //      theList.insertCurrent(5.99);  
  22. //      theList.insertCurrent(6.99);  
  23. //      theList.insertCurrent(7.99);  
  24. //      theList.insertCurrent(8.99);  
  25. //      theList.insertCurrent(9.99);  
  26. //      theList.delete();  
  27. //      theList.displayList();  
  28.         
  29.       int input;  
  30.       int i;  
  31.         while(true)  
  32.         {      
  33.             System.out.print("Enter the total number of the people: ");  
  34.             System.out.flush();  
  35.             input=Integer.parseInt(getString());  
  36.             RecycleLinkList theList=new RecycleLinkList(input);  
  37.             for(i=0;i<input;i++)                       //插入赋值  
  38.             {  
  39.                 theList.insertCurrent(i+1);  
  40.                   
  41.             }  
  42.             System.out.print("Enter the start number of the Joseph circle : ");//输入起始编号  
  43.             input=Integer.parseInt(getString());  
  44.             for(i=0;i<input;i++)theList.step();  
  45.             System.out.print("Enter the number we call: ");                  //输入间隔数目  
  46.             input=Integer.parseInt(getString());  
  47.             while(theList.TotalNum>1)  
  48.             {  
  49.                 for(i=0;i<input-2;i++)  
  50.                 {  
  51.                     theList.step();  
  52.                 }  
  53.                 theList.delete();  
  54.                 theList.displayList();  
  55.             }  
  56.               
  57.             //System.out.println("Postfix is: "+output+'/n');  
  58.         }//end while  
  59.     }//end main  
  60.     //...........................................................  
  61. public static String getString()throws IOException    
  62. {  
  63.     InputStreamReader in=new InputStreamReader(System.in);  
  64.     BufferedReader br=new BufferedReader(in);  
  65.     String s=br.readLine();  
  66.     return s;  
  67. }  
  68.       
  69.   
  70. }  

模拟结果如下:

Code:
  1. Enter the total number of the people: 7  
  2. Enter the start number of the Joseph circle : 1  
  3. Enter the number we call: 4  
  4. List(first-->last):{2.0}{1.0}{7.0}{6.0}{5.0}{3.0}  
  5.   
  6. List(first-->last):{5.0}{3.0}{2.0}{1.0}{6.0}  
  7.   
  8. List(first-->last):{6.0}{5.0}{3.0}{1.0}  
  9.   
  10. List(first-->last):{6.0}{5.0}{1.0}  
  11.   
  12. List(first-->last):{5.0}{6.0}  
  13.   
  14. List(first-->last):{6.0}  
  15.   
  16. Enter the total number of the people:   

 

     

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值