3.10 約瑟夫環問題--循環單鏈表解決

/***************************************************************
*約瑟夫環問題
*問題描述:N個人做成一圈,從第K個人開始報數遊戲(從0開始報數),
          報M的出列,最後剩下的一個人獲勝
*算法: 循環單鏈表(無頭節點)
*新建單鏈表:  返回value最小的節點當作"head",新建過程即是插入過程
*刪除(出列操作):        記錄前驅,方便刪除
*author:fangchang
*time: 2016/04/04 18:25
****************************************************************/

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

#define N 5           //N個人,環長
#define M 1           //M次傳遞後,刪除當前人
#define K 2          //從第K個人開始遊戲

typedef struct node {
	int value;
	struct node * next;
}*pnode;
typedef pnode circleList;

circleList createCircleList();
void answer();
int main() {
	answer();
	fflush(stdin);
	getc(stdin);
	return 0;
}


void answer() {
	circleList clist = createCircleList();
	int j=0;
	circleList cur=clist;
	while(cur->value!=K) {
		cur = cur->next;            //尋找遊戲起點(K)
	}
	circleList pre=clist;
	while(pre->next!=cur) {          //尋找遊戲起點人的前驅
		pre=pre->next;
	}
	//以下是core code
	while(pre->next!=pre) {         //循環終止條件
		while(j<M) {                //查找應該被刪除的節點
			pre=cur;
			cur=cur->next;
			++j;
		}
		pre->next=cur->next;       //開始刪除節點
		printf("delete %d\n",cur->value);
		free(cur);
		cur=pre->next;
		j=0;
	}
	//以上是core code
	printf("The winner is %d\n",pre->value);
}
circleList createCircleList() {                  //新建循環單鏈表,無頭指針
	int i;
	circleList cur,pre;
	circleList firstNode;
	for(i=0;i<N;++i) {
		cur=(circleList)malloc(sizeof(struct node));
		if(!cur) {
			return NULL;
		}
		cur->value=i+1;
		cur->next=cur;                    //單節點循環
		if(i==0) {                        //返回value最小的節點當作"head"
			firstNode = cur;           
			pre=cur;
		}
		else {                            //插入
			cur->next = pre->next;
			pre->next=cur;
			pre=cur;
		}
	}
	return firstNode;
}

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