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;
//}