數據結構與算法(4、約瑟夫環問題到循環鏈表)

首先先解釋約瑟夫環問題,這個問題,背景其實挺殘酷的,來自於一場自殺遊戲,舉個現實的例子,如果你有4個朋友,但是隻能給一個人帶飯,那麼做這樣的遊戲,4個人圍成一個環,你說從1開始數,數到2,就淘汰掉2,剩下的繼續圍成一個環,在繼續這個遊戲,直到剩下一個爲止。
表達能力有限,直接百度百科!
約瑟夫環(約瑟夫問題)是一個數學的應用問題:已知n個人(以編號1,2,3…n分別表示)圍坐在一張圓桌周圍。從編號爲k的人開始報數,數到m的那個人出列;他的下一個人又從1開始報數,數到m的那個人又出列;依此規律重複下去,直到圓桌周圍的人全部出列。通常解決這類問題時我們把編號從0~n-1,最後結果+1即爲原問題的解。
那麼如何構建環以及如何進行刪除操作是最重要的了!

構建之前,我們要有一個已經存在的tail,有無數據不重要,

首先是構建的問題:

//實現一個插入操作
void addElements(int value){
   if(tail==nullptr){
   //第一種情況是鏈表裏面沒有任何的結點,那麼新建的結點有特殊的操作,指向自己,形成一個環
    tail=new node(value);
    //讓tail指向自己,形成一個小環
    tail->next=tail;
   }else{
    //新建結點
    node * new_node=new node(value);
    //讓原來的結點的next指向變成此時新結點的指向
    new_node->next=tail->next;
    //讓tail指向新結點,形成一個環
    tail->next=new_node;
    //讓新結點成爲tail,繼續進行下一步的增加操作,循環往復
     tail=new_node;
   }
}

構建完約瑟夫之後,接下來是一個刪除操作

/*index表示需要輸入的數*/
void delete(index){
//設置臨時變量
  node*p=tail;
  //避免程序拋出nullPointexception
  if(p!=nullptr&&p->next!=p){
     for(int i=0;i<index-1;i++){
     p=p->next;
     }
  }
  node * delete_element=p->next;
  p->next=p->next->next;
  if(delete_element==tail)
  tail=p;
  //C++實現,需要釋放內存
  delete delete_element;
}

如此就可以實現一個約瑟夫環的構建與刪除的問題,總結一下:
1、在構建的時候,首先意識到這個是一個圓環,所以哪怕是一個元素,也要讓它指向自己。
2、在構建新結點的時候,需要讓tail原本的關係給新結點,然後再指向新結點,不可以顛倒順序,不然會丟失原結點的關係

從約瑟夫環衍生到循環鏈表,其實約瑟夫環就是一個循環鏈表,哈哈哈

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章