猿问

求大神帮忙写一个程序,急用,拜托了。11.15晚上之前要

实验一  线性表的应用

实验目的和要求:

通过实验进一步理解线性表的逻辑结构和存储结构,提高使用理论知识指导解决实际问题的能力,熟练掌握链表的实际应用。

主要内容:

题目1 

问题描述:

编号为1,2,…,nn个人按顺时针方向围坐一圈,任选一个正整数作为报数上限值m,任选一个人(编号为k)开始按顺时针方向自1开始顺序报数,报到m时停止报数,报m的人出列,从他在顺时针方向上的下一个人开始重新从1报数,报到m时停止报数,报m的人出列,如此下去,直到所有人全部出列为止。试设计一个程序求出出列顺序。

基本要求:

利用单向循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。



 


小小雨点
浏览 1513回答 2
2回答

Yexiaomo

说一下思路,  创建, 遍历, 求长度... 略 主要是 viewList() 函数中的 那个 while() 循环有点绕, 本来想的是 , 当 计数 达到上限时, 就把这个值 输出, 然后 将这个结点从链表中删除 当写写发现, 每个好的标志, 早知道就在结构体中 多加一个 指示变量了, (输出过就 跳过, 没有输出过, 计数器 就加 1 ) 这个还是有点麻烦的. 加了一个指针 永远指向 所 删除结点的 前面的那个结点,  这样写, 还是有点不好的....这是测试后代码:#include <stdio.h> #include <stdlib.h> #include <malloc.h> typedef struct Node{ int data; struct Node *pNext; } LNode, *LIST; /*函数声明*/ LIST createList(); void traverseList(LIST pHead); int  ListLength(LIST pHead); void viewList(LIST pHead); int main(){ LIST List = createList();  // 创建  traverseList( List );    // 遍历第一次  viewList(List);              // 输出  return 0;         } /* 单循环链表的创建不用注释了吧 */  LIST createList() { int n, i; LIST pNew, pHead, pTail; //定义头结点, 尾结点  pHead = (LIST)malloc(sizeof(LNode)); if(pHead == NULL){ exit(-1); } pTail = pHead; printf("输入人数: "); scanf("%d", &n); for(i = 0; i < n; ++i){ pNew = (LIST)malloc(sizeof(LNode)); if(pHead == NULL){ exit(-1); } pNew->data = i+1; pTail->pNext = pNew; pTail = pNew;//始终将新产生的结点作为尾结点  } pTail->pNext = pHead; return pHead; } /* 遍历 */  void traverseList(LIST pHead){ LIST p = pHead->pNext; while(p != pHead){ printf("%d ", p->data); p = p->pNext;  } printf("\n"); return ; } /* 求长度,  和遍历差不多 */  int  ListLength(LIST pHead){ int len = 0; LIST p = pHead->pNext; while(p != pHead){ ++len; p = p->pNext;  } return len; }  /* 这个是主要的 */  void viewList(LIST pHead){ int i = 1; int j = 0; int cnt = 1; //作为计数 int max;//最大上限 //首先链表不能为空 if( pHead->pNext == pHead){ return ;  }  //最大上限不能为小于 0 的数  printf("输入报数最大上限为: "); scanf("%d", &max); if(max <= 0){ printf("输入报数最大上限值有误,程序终止!!!\n "); exit(-1); } printf("\n"); //人员编号不能超过实有人数 && 不能为负  printf("输入第一个报数的人员的编号: "); scanf("%d", &j); if(j < 1 || j > ListLength(pHead)){ printf("输入第一个报数的人员的编号 有误!!!\n 程序退出!"); exit(-1) ;  }  // 将 p 指向第一个报数的员工  LIST p = pHead->pNext; LIST pp = pHead;//pp 永远指向 p 指向的前面的那个结点  LIST q; //作为临时存储 需删除的结点  while(p != pHead){ if(i == j) break; p = p->pNext; pp = pp->pNext;   ++i; }  /*  这个循环是重点 */  while( ListLength(pHead) != 0){ if( cnt != max ) { p = p->pNext; pp = pp->pNext ; if(p != pHead) ++cnt; } else { printf("%d ", p->data); q = p; p = p->pNext; pp->pNext = p; free(q); cnt = 1; } }   }这是所有代码, 包括垃圾代码, 各种思路, 虽然不是很重要, 但我觉得还是有必要#include <stdio.h> #include <stdlib.h> #include <malloc.h> #define OK 1 #define ERROR 0 typedef struct Node{ int data; struct Node *pNext; } LNode, *LIST; LIST createList(); void traverseList(LIST pHead); int  ListLength(LIST pHead); void viewList(LIST pHead); void deleteList(LIST pHead, int pos); int main(){ int i; LIST List = createList(); traverseList( List ); // for(i = 1;  i <= 11; ++i){ // deleteList(List, 1); // traverseList( List ); // } viewList(List); return 0; } LIST createList() { int n, i; LIST pNew, pHead, pTail; //定义头结点, 尾结点  pHead = (LIST)malloc(sizeof(LNode)); if(pHead == NULL){ exit(-1); } pTail = pHead; printf("输入人数: "); scanf("%d", &n); for(i = 0; i < n; ++i){ pNew = (LIST)malloc(sizeof(LNode)); if(pHead == NULL){ exit(-1); } pNew->data = i+1; pTail->pNext = pNew; pTail = pNew;//始终将新产生的结点作为尾结点  } pTail->pNext = pHead; return pHead; } void traverseList(LIST pHead){ LIST p = pHead->pNext; while(p != pHead){ printf("%d ", p->data); p = p->pNext;  } printf("\n"); return ; } int  ListLength(LIST pHead){ int len = 0; LIST p = pHead->pNext; while(p != pHead){ ++len; p = p->pNext;  } return len; }  void viewList(LIST pHead){ int i = 1; int j = 0; int cnt = 1; //作为计数 int max;//最大上限 //首先链表不能为空 if( pHead->pNext == pHead){ return ;  }  //最大上限不能为小于 0 的数  printf("输入报数最大上限为: "); scanf("%d", &max); if(max <= 0){ printf("输入报数最大上限值有误,程序终止!!!\n "); exit(-1); } printf("\n"); //人员编号不能超过实有人数 && 不能为负  printf("输入第一个报数的人员的编号: "); scanf("%d", &j); if(j < 1 || j > ListLength(pHead)){ printf("输入第一个报数的人员的编号 有误!!!\n 程序退出!"); exit(-1) ;  }  // 将 p 指向第一个报数的员工  LIST p = pHead->pNext; LIST pp = pHead;//pp 永远指向 p 指向的前面的那个结点  LIST q; //作为临时存储 需删除的结点  while(p != pHead){ if(i == j) break; p = p->pNext; pp = pp->pNext;   ++i; }  while( ListLength(pHead) != 0){ if( cnt != max ) { p = p->pNext; pp = pp->pNext ; if(p != pHead) ++cnt; } else { printf("%d ", p->data); q = p; p = p->pNext; pp->pNext = p; free(q); cnt = 1; } }   } //void deleteList(LIST pHead,int i) /* 改变pHead */ //{ /* 删除pHead的第i个元素 */ //  LIST p=pHead->pNext,q; /* p指向头结点 */ //  int j=0; //  if( i <= 0 || i > ListLength(pHead) ) /* 第i个元素不存在 */ //    return ; //  while( j < i-1) /* 寻找第i-1个结点 */ //  { //    p = p->pNext; //    j++; //  } //  q=p->pNext; /* q指向待删除结点 */ //  p->pNext=q->pNext; // //  if(pHead==q) /* 删除的是表尾元素 */ //    pHead=p; //  free(q); /* 释放待删除结点 */ //  return ; //} //void deleteList(LIST pHead, int pos){ //    int i = 0; //    LIST p, q; //    p = pHead; //    if( i > pos-1 && i > ListLength(pHead)) //        return; //    while( p->pNext != pHead && i < pos-1 ) { //        p = p->pNext; //        ++i; //    } //     //    q = p->pNext; //    p->pNext = q->pNext; //     //    if(pHead->pNext==q) /* 删除的是表尾元素 */ //     pHead=p; //   free(q); /* 释放待删除结点 */ //     //    return;  //}

慕数据5775487

这个真不会
随时随地看视频慕课网APP
我要回答