为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C
小小雨点 2016-11-15 01:38:06
实验一  线性表的应用实验目的和要求:通过实验进一步理解线性表的逻辑结构和存储结构,提高使用理论知识指导解决实际问题的能力,熟练掌握链表的实际应用。主要内容:题目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 反对 回复 2016-11-15
点击展开后面3
?
慕数据5775487

TA贡献76条经验 获得超19个赞

这个真不会

查看完整回答
反对 回复 2016-11-15
  • 2 回答
  • 0 关注
  • 1512 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信