約瑟夫環問題編程實現

問題:

約瑟夫環(約瑟夫問題)是一個數學的應用問題:已知n個人(以編號1,2,3…n分別表示)圍坐在一張圓桌周圍。從編號爲k的人開始報數,數到m的那個人出列;他的下一個人又從1開始報數,數到m的那個人又出列;依此規律重複下去,直到圓桌周圍的人全部出列。通常解決這類問題時我們把編號從0~n-1,最後[1] 結果+1即爲原問題的解

問題分析

  • 構建一個環(由鏈表來構建)最後一個的指針指向我們最開始的節點
  • 環遍歷刪除問題
    • 特別是剩下兩個元素時需要進行的操作

linkRing.h

#ifndef _LINK_RING_H_
#define _LINK_RING_H_
#include <assert.h>
#include <malloc.h>
#include <memory.h>
struct NodeT{
    int data;           //數據域
    struct NodeT * next; //指針域 
};

typedef struct NodeT * PNode;
typedef struct NodeT Node;

PNode createRing(int num);  //創建環的個數
//void delNext(PNode pNode); //這個用不着,在遍歷刪除時已經進行了
int ring(PNode pNode,int num) ;  //約瑟夫環的遍歷函數

#endif // _LINK_RING_H_

linkRing.c

#include "linkRing.h"
//創建環的個數
PNode createRing(int num)
{
    PNode p,pNode;
    int i = 0;
    assert(num>0);
//    pNode=(PNode)calloc(1,sizeof(Node));//分配內存空間
    //pNode=(PNode)calloc(1,sizeof(Node));
    for(i = 0;i<num;i++)
    {
        if(i == 0)
        {
       //頭節點的創建
           pNode = p = (PNode)calloc(1,sizeof(Node));
        }
        else {
           p->next = (PNode)calloc(1,sizeof(Node));
           p = p->next;
        }

        p->data = i+1;
        p->next = NULL;
    }
    p->next = pNode;  //將這個數據形成一個環,鏈表的最後一個節點指向頭節點
    return pNode;
}
//void delNext(PNode pNode)
//{
//    PNode p = NULL;
//    assert(pNode!=NULL);
//    if(pNode->next == NULL)
//    {
//       printf("this node don't have next node");
//    }
//    else{
//        p = pNode->next;
//        pNode->next = p->next;
//        free(p);
//        p = NULL;
//    }
//}
int ring(PNode pNode,int num)  //第幾個出局
{
   PNode p = NULL;
   int i = 1;
   assert(pNode!=NULL);
   while(pNode->next != NULL)
   {
      if(i == num-1)
      {
         p = pNode->next;
         if(p->next == pNode)   //當只存在兩個數據時,pNode->next = p; p->next = pNode;刪除數據的方式
         {
            printf("current out num is:%d\n",p->data);
            free(p);
            pNode->next = NULL;
            break;
         }
         else{
        //其他刪除數據的方式
            pNode->next = p->next;
            printf("current out num is:%d\n",p->data);
            free(p);
            i = 0;   //當前值爲pNode,沒有向後移動
            p = NULL;
         }
      }
      pNode = pNode->next;
      i++;
   }
   return pNode->data;
}

測試的main

#include <stdio.h>
#include <stdlib.h>
#include "linkRing.h"

int main()
{
    PNode pNode = NULL;
    pNode = createRing(5);
    printf("最終的結果是:%d",ring(pNode,3));
    return 0;
}

結果截圖:

這裏寫圖片描述

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