c语言数据结构之单向循环链表约瑟夫问题

来源:互联网 发布:淘宝投诉电话是多少呢 编辑:程序博客网 时间:2024/05/18 04:00

问题描述:

约瑟夫问题的一种描述是:编号为12,……,nn个人按顺时针方向坐一圈,没人持有一个密码(正整数)。一开始任选一个作为报数上限值m,从第一个开始顺时针自1开始顺序报数,报到m是停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向的下一个人重新从1报数,如此下去,直到所有的人全部出列为止。设计一个程序,求出出列顺序


废话不多说,上代码:


/*==========Definition.h==============*//*标准库函数*/#include<string.h>#include<ctype.h>#include<malloc.h>#include<limits.h>#include<stdio.h>#include<stdlib.h>#include<io.h>#include<math.h>#include<process.h>/*常量定义*/#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define LIST_INIT_SIZE 5 /*循环链表存储空间的初始分配量*//*类型定义*//*Status是函数的类型,其值是函数结果状态代码,如OK等*/typedef int Status;/*Boolean是布尔类型,其值是TRUE或FALSE*/typedef int Boolean;/*演示程序设定元素类型为int,如有必要可以修改成其他类型*/typedef int ElemType;/*线性表的链式存储结构*/struct Node{   ElemType data; /*数据域*/   struct Node * next; /*后继指针域*/   ElemType bianhao;};typedef struct Node LinkNode;typedef struct Node * LinkList;/*=======循环链表功能模块========*//*正序构造一个循环链表,并使用参数L返回*/Status Initialize(LinkList&L,int n){/*产生头结点,并使L指向此头结点。此语句等价于:L=(LinkList)malloc(sizeof(struct Node)); */L=(LinkList)malloc(sizeof(LinkNode));if(!L) /*存储分配失败*/exit(OVERFLOW);/*指针域暂时置为空*/L->next=NULL;LinkList p,q;q=L;for(int i=0;i<n;i++){/*生成新的有效数据结点*/p=(LinkList)malloc(sizeof(LinkNode));scanf("%d",&p->data);p->bianhao=i+1;/*该语句不能省,否则会造成程序异常*/p->next=NULL;q->next=p;        q=p;}q->next=L;scanf("&d",L->data);L->bianhao=n;return OK;}/*=======在带头节点的循环链表L中,删除第i个元素,并由e返回其值========*/Status LinkDelet(LinkList&L, int i, ElemType  &e,ElemType &n){    LinkList p=L;int j = 0;while (p->next&&j < i - 1)       //查找到第i-1个节点{p = p->next;++j;}LinkList q;                   //删除第i个结点    q = p->next;    p->next = q ->next;e = q->data;    n=q->bianhao;free(q);L=p;return OK;}  /*==================解决约瑟夫问题================*/int main(){    int mima,m,n,bianhao,num;    LinkList L;    printf("=====下面为约瑟夫排序问题的计算过程及结果=====\n");    printf("请输入环中元素的个数(正整数):");    scanf("%d",&n);      printf("请输入%d个数据元素(每次输入一个元素后空格,全部输完以后回车):",n);    Initialize(L,n);printf("请输入上限值m:");    scanf(" %d",&m);printf("出列顺序为:");    for(int i=0;i<n;i++)    {        LinkDelet(L,m,mima,bianhao);m=mima;        printf(" %d",bianhao);    }printf("\n");return 0;}



一开始,创建循环链表是把我难住了,虽然书上说的很简单,但是一开始我的链表是带头结点的,而且并不打算在头结点存值,所以把尾结点指向头结点的下一个结点,循环起来难免出错。于是最后只得妥协,先将尾结点的下一个结点指向头结点,同时给头结点赋值,这样才输出正确的结果。



运行结果