实验一 线性表的应用实验目的和要求:通过实验进一步理解线性表的逻辑结构和存储结构,提高使用理论知识指导解决实际问题的能力,熟练掌握链表的实际应用。主要内容:题目1 :问题描述:编号为1,2,…,n的n个人按顺时针方向围坐一圈,任选一个正整数作为报数上限值m,任选一个人(编号为k)开始按顺时针方向自1开始顺序报数,报到m时停止报数,报m的人出列,从他在顺时针方向上的下一个人开始重新从1报数,报到m时停止报数,报m的人出列,如此下去,直到所有人全部出列为止。试设计一个程序求出出列顺序。基本要求:利用单向循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。
2 回答
已采纳
Yexiaomo
TA贡献152条经验 获得超157个赞
说一下思路, 创建, 遍历, 求长度... 略 主要是 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; //}
- 2 回答
- 0 关注
- 1499 浏览
添加回答
举报
0/150
提交
取消