约瑟夫环:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
定义很简单,根据定义,采用循环链表来实现,有一点需要注意的是边界问题,把边界问题处理好了,程序就容易真正实现了。以下是代码:
//约瑟夫环 #include<stdio.h> #include<stdlib.h> typedef struct Linklist { int data; struct Linklist * next; }ListNode,*List; //约瑟夫还 void Josephus( int n, int k, int m); int main() { Josephus(9,1,5); } //约瑟夫还 //n为总人数,k为第一个开始报数的人,m为出列者喊到的数 void Josephus( int n, int k, int m) { // p为当前结点,r为辅助结点,指向p的前驱结点,L为头节点 List p,r,L; p = r = L = NULL; int i; for ( i = 0; i < n; i++ ) { p = (List)malloc(sizeof(ListNode)); p->data = i + 1; if ( L == NULL ) { L = p; r = p; } else { r->next = p; r = p; } } //使链表连起来 p->next = L; //打印链表 p = L; printf("链表元素:"); for ( i = 0; i < n; i++ ) { printf("%4d",p->data); p = p->next; } p = L; //把指针指向第一个报数的人 for ( i = 1; i < k; i++ ) { r = p; p = p->next; } printf("\n出列顺序:"); //循环的删除队列结点 while ( p->next != p ) { for ( i = 0; i < m - 1; i++ ) { r = p; p = p->next; } //指向的是第一个人,则将r指向最后一个元素 if ( p == L ) { L = p->next; r = p; while( r->next != p ) r = r->next; } r->next = p->next; printf("%4d",p->data); free(p); p = r->next; } printf("%4d\n",p->data); }
作者:cqnuztq 发表于2013-5-2 16:59:14 原文链接
阅读:43 评论:0 查看评论