数据结构实验题参考答案.docx
- 文档编号:5113257
- 上传时间:2022-12-13
- 格式:DOCX
- 页数:32
- 大小:39.84KB
数据结构实验题参考答案.docx
《数据结构实验题参考答案.docx》由会员分享,可在线阅读,更多相关《数据结构实验题参考答案.docx(32页珍藏版)》请在冰豆网上搜索。
数据结构实验题参考答案
【实验题】
1.狐狸逮兔子
围绕着山顶有10个圆形排列的洞,狐狸要吃兔子,兔子说:
“可以,但必须找到我,我就藏身于这十个洞中,你先到1号洞找,第二次隔1个洞(即3号洞)找,第三次隔2个洞(即6号洞)找,以后如此类推,次数不限。
”但狐狸从早到晚进进出出了1000次,仍没有找到兔子。
问兔子究竟藏在哪个洞里?
(提示:
这实际上是一个反复查找线性表的过程。
)
【数据描述】
定义一个顺序表,用具有10个元素顺序表来表示这10个洞。
每个元素分别表示围着山顶的一个洞,下标为洞的编号。
#define LIST_INIT_SIZE 10 //线性表存储空间的初始分配量
typedef struct {
ElemType *elem; //存储空间基址
int length; //当前长度
int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位)
}SqList;
【算法描述】
status InitList_Sq(SqList &L) {
//构造一个线性表L
L.elem=(ElemType )malloc(LIST_INIT_SIZE*sizeof(ElemType));
If(!
L.elem) return OVERFLOW;//存储分配失败
L.length=0; //空表长度为0
L.listsize=LIST_INIT_SIZE; //初始存储容量
return OK;
} //InitList_Sq
status Rabbit(SqList &L)
{ //构造狐狸逮兔子函数
int current=0; //定义一个当前洞口号的记数器,初始位置为第一个洞口
for(i=0;i L.elem[i]=1;//给每个洞作标记为1,表示狐狸未进之洞 L.elem[LIST_INIT_SIZE-1]=L.elem[0]=0;//首先进入第一个洞,标记进过的洞为0。 for(i=2;i<=1000;i++) { current=(current+i)%LIST_INIT_SIZE;//实现顺序表的循环引用 L.elem[i]=0;// 标记进过的洞为0 }//第二次隔1个洞找,第三次隔2个洞找,以后如此类推,经过一千次 printf("兔子可能藏在如下的洞中: ") for(i=0;i if(L.elem[i]==1) printf(“ 第%d个洞\n ”,i+1);//输出未进过的洞号 return OK; }//end 【C源程序】 #include #include #define OK 1 #define OVERFLOW -2 typedef int status; typedef int ElemType; #define LIST_INIT_SIZE 10 /*线性表存储空间的初始分配量 */ typedef struct { ElemType *elem; /* 存储空间基址 */ int length; /* 当前长度 */ int listsize; /*当前分配的存储容量(以sizeof(ElemType)为单位)*/ }SqList; status InitList_Sq(SqList *L){ /*构造一个线性表L */ (*L).elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType)); if(! ((*L).elem)) return OVERFLOW; /* 存储分配失败 */ (*L).length=0; /*空表长度为0 */ (*L).listsize=LIST_INIT_SIZE; /*初始存储容量 */ return OK; } /*InitList_Sq */ status Rabbit(SqList *L){ /*构造狐狸逮兔子函数 */ int i,current=0; /*定义一个当前洞口号的记数器,初始位置为第一个洞口*/ for(i=0;i (*L).elem[i]=1;/*给每个洞作标记为1,表示狐狸未进之洞 */ (*L).elem[LIST_INIT_SIZE-1]=0; (*L).elem[0]=0; /*第一次进入第一个洞,标记进过的洞为0 */ for(i=2;i<=1000;i++) { current=(current+i)%LIST_INIT_SIZE;/*实现顺序表的循环引用 */ (*L).elem[current]=0;/* 标记进过的洞为0 */ }/*第二次隔1个洞找,第三次隔2个洞找,以后如此类推,经过一千次 */ printf("\n兔子可能藏在如下的洞中: ") ; for(i=0;i if((*L).elem[i]==1) printf(" \n此洞是第%d号洞 ",i+1);/*输出未进过的洞号 */ return OK; } void main() { SqList *L; InitList_Sq(L); Rabbit(L); getch(); } 【测试数据】 最后的输出结果为: 2 4 7 9 【说明】 本算法思路比较简单,采用了顺序表表示围着山顶的10个洞,首先对所有洞设置标志为1,然后通过1000次循环,对每次所进之洞修改标志为0,最后输出标志为1的洞。 2.银行客户 某银行有一个客户办理业务站,在单位时间内随机地有客户到达,设每位客户的业务办理时间是某个范围内的随机值。 设只有一个窗口,一位业务人员,要求程序模拟统计在设定时间内,业务人员的总空闲时间和客户的平均等待时间。 假定模拟数据已按客户到达的先后顺序依次存于某个正文数据文件中。 对应每位客户有两个数据,到达时间和需要办理业务的时间。 复习概念: 与栈相对应,队列是一种先进先出的线性表。 它只允许在表的一端进行插入,而在另一端进行删除元素。 允许插入的一端称队尾,允许删除的一端称队头。 插入与删除分别称为入队与出队。 队列示意图见图3-2: 出队 ←a1 a2 …… an-1 ←an进队 队头 队尾 【数据描述】 typedef struct{ int arrive; int treat;//客户的信息结构 }QNODE; typedef struct node{ QNODE data; Struct node *next;//队列中的元素信息 }LNODE LNODE *front,*rear;// 队头指针和队尾指针 【算法描述】 { 设置统计初值; 设置当前时钟时间为0; 打开数据文件,准备读; 读入第一位客户信息于暂存变量中; do{ //约定每轮循环,处理完一位客户 if(等待队列为空,并且还有客户){ //等待队列为空时 累计业务员总等待时间; 时钟推进到暂存变量中的客户的到达时间; 暂存变量中的客户信息进队; 读取下一位客户信息于暂存变量; } 累计客户人数; 从等待队列出队一位客户; 将该客户的等待时间累计到客户的总等待时间; 设定当前客户的业务办理结束时间; while(下一位客户的到达时间在当前客户处理结束之前){ 暂存变量中的客户信息进队; 读取下一位客户信息于暂存变量; } 时钟推进到当前客户办理结束时间; }while(还有未处理的客户); 计算统计结果,并输出; 【C源程序】 #include #include #define OVERFLOW -2 typedef struct{ int arrive; int treat; /*客户的信息结构*/ }QNODE; typedef struct node{ QNODE data; struct node *next; /*队列中的元素信息*/ }LNODE; LNODE *front,*rear;/* 队头指针和队尾指针*/ QNODE curr,temp; char Fname[120]; FILE *fp; void EnQueue(LNODE **hpt,LNODE **tpt,QNODE e){ /*队列进队*/ LNODE *p=(LNODE *)malloc(sizeof(LNODE)); if(! p) exit(OVERFLOW); /*存储分配失败*/ p->data=e; p->next=NULL; if(*hpt==NULL) *tpt=*hpt=p; else *tpt=(*tpt)->next=p; } int DeQueue(LNODE **hpt,LNODE **tpt,QNODE *cp){ /*链接队列出队*/ LNODE *p=*hpt; if(*hpt==NULL) return 1;/*队空*/ *cp=(*hpt)->data; *hpt=(*hpt)->next; if(*hpt==NULL) *tpt=NULL; free(p); return 0; } void main() { int dwait=0,clock=0,wait=0,count=0,have=0,finish; printf("\n enter file name: "); scanf("%s",Fname);/*输入装客户模拟数据的文件的文件名*/ if((fp=fopen(Fname, "r"))==NULL){ /*打开数据文件*/ printf("cannot open file %s",Fname); return; } front=NULL;rear=NULL; have=fscanf(fp, "%d%s",&temp.arrive,&temp.treat); do{ /*约定每轮循环,处理一位客户*/ if(front==NULL && have==2){ /*等待队列为空,但还有客户*/ dwait+=temp.arrive-clock; /*累计业务员总等待时间*/ clock=temp.arrive; /*时钟推进到暂存变量中的客户的到达时间*/ EnQueue(&front,&rear,temp); /* 暂存变量中的客户信息进队*/ have=fscanf(fp, "%d%d",&temp.arrive,&temp.treat); } count++; /*累计客户人数*/ DeQueue(&front,&rear,&curr);/*出队一位客户信息*/ wait+=clock-curr.arrive; /*累计到客户的总等待时间*/ finish=clock+curr.treat;/*设定业务办理结束时间;*/ while(have==2 && temp.arrive<=finish){ /*下一位客户的到达时间在当前客户处理结束之前*/ EnQueue(&front,&rear,temp);/* 暂存变量中的客户信息进队*/ have=fscanf(fp, "%d%d",&temp.arrive,&temp.treat); } clock=finish; /* 时钟推进到当前客户办理结束时间*/ }while(have==2 || front! =NULL); printf("结果: 业务员等待时间%d\n客户平均等待时间%f\n",dwait, (double)wait/count); printf("模拟总时间: %d,\n客户人数: %d,\n总等待时间: %d\n",clock, count,wait); getch(); }/*main_end*/’ 【测试数据】 设数据装在一个数据文件data.dat中,内容为: 10 6 13 8 显示结果为: enter file name: data.dat enterfilename: data.dat 结果: 业务员等待时间10 客户平均等待时间25.500000 模拟总时间: 72, 客户人数: 2, 总等待时间: 51 【说明】 在计算程序中,程序按模拟环境中的事件出同顺序逐一处理事件: 当一个事件结束时,下一个事件隔一段时间才发生,则程序逻辑的模拟时钟立即推进到下一事件的发生时间;如一个事件还未处理结束之前,另有其他事件等待处理,则这些事件就应依次排队等候处理。 3.二叉树的的应用: 设计一个表示家谱的二叉树 要求: 采用一棵二叉树表示一逐步形成家谱关系,对于给定的父亲显示所有的儿子。 由于家谱为树形,但不是一棵二叉树,所以在存储时要转换成二叉树的形式。 规定: 一个父亲结点的左子树表示母亲结点,母亲结点的右子树表示他们的所有儿子,例如,图1是一个用二叉树表示的家谱图,与之对应的传统树形图家谱图如图2所示。 这样就将家谱树转换成二叉树了,而二叉树的操作是容易实现的。 图2一个家谱树 图1二叉树表示的家谱图 [C源程序] #include #include #include #defineMaxWidth40 #defineMaxSize30 typedefstructtreenode { charname[10]; structtreenode*left,*right; }*BTree; BTreefindfather(BTreep,charxm[]) { BTreebt; if(p==NULL)return(NULL); else { if(strcmp(p->name,xm)==0) return(p); else { bt=findfather(p->left,xm); if(bt! =NULL)return(bt); elsereturn(findfather(p->right,xm)); } } } BTreecreatree() { intn,m,i,contin=1,first=1; charxm[10]; BTreebtree,s,t,p; printf("\n建立一个家谱二叉树(以空格结尾): \n"); while(contin) { if(first==1) { btree=(BTree)malloc(sizeof(structtreenode)); printf("\t姓名: "); gets(btree->name); btree->right=NULL; s=(BTree)malloc(sizeof(structtreenode)); printf("\t妻子: "); gets(s->name); s->left=s->right=NULL; btree->left=s; first=0; } else { printf("\t父亲: "); gets(xm); if(strcmp(xm,"")==0) contin=0; else { p=findfather(btree,xm); if(p! =NULL) { p=p->left; if(p==NULL)/*没有妻子*/ printf("\t没有儿子(因为没有妻子)\n"); else { while(p->right! =NULL)p=p->right; s=(BTree)malloc(sizeof(structtreenode)); s->right=NULL; p->right=s; printf("\t儿子: "); gets(s->name); printf("\t儿妻: "); gets(xm); if(strcmp(xm,"")! =0) { t=(BTree)malloc(sizeof(structtreenode)); strcpy(t->name,xm); t->left=t->right=NULL; s->left=t; } elses->left=NULL; } } elseprintf("不存在这样的父结点! \n"); } } } return(btree); } voiddisptree(BTreeBT) { BTreestack[MaxSize],p; intlevel[MaxSize][2],top,n,i,width=4; if(BT! =NULL) { printf("\n家谱凹入表示法: \n"); top=1; stack[top]=BT;/*根结点入栈*/ level[top][0]=width; while(top>0) { p=stack[top];/*退栈并凹入显示该结点值*/ n=level[top][0]; for(i=1;i<=n;i++)/*其中n为显示场宽,字符以右对齐显示*/ printf(""); printf("%6s",p->name); for(i=n+1;i<=MaxWidth-6;i+=2) printf("━"); printf("\n"); top--; if(p->right! =NULL) {/*将右子树根结点入栈*/ top++; stack[top]=p->right; level[top][0]=n+width;/*显示场宽增width*/ level[top][1]=2; } if(p->left! =NULL) {/*将左子树根结点入栈*/ top++; stack[top]=p->left; level[top][0]=n+width;/*显示场宽增width*/ level[top][1]=1; } } } } voidfindson(BTreebt) { charxm[10]; BTreep; printf("\n查找指定父亲的所有儿子\n"); printf("父亲: "); gets(xm); p=findfather(bt,xm); if(p==NULL) printf("不存在%s的父亲! \n",xm); else { p=p->left; p=p->right; if(p==NULL) printf("%s没有儿子! \n",xm); else { printf("%s有以下儿子! \n\t"); while(p! =NULL) { printf("%8s",p->name); p=p->right; } } } } main() { BTreebt; bt=creatree(); disptree(bt); findson(bt); } [运行结果] 建立一个家谱二叉树(以空格结尾): 姓名: 张德 妻子: 陈氏 父亲: 张德 儿子: 张文 儿妻: 刘氏 父亲: 张德 儿子: 张武 儿妻: 王氏 父亲: 张文 儿子: 张兵 儿妻: 李氏 父亲: 张文 儿子: 张强 儿妻: 父亲: 张武 儿子: 张华 儿妻: 父亲: 家谱凹入表示法: 张德━━━━━━━━━━━━━━━ 陈氏━━━━━━━━━━━━━ 张文━━━━━━━━━━━ 刘氏━━━━━━━━━ 张兵━━━━━━━ 李氏━━━━━ 张强━━━━━ 张武━━━━━━━━━ 王氏━━━━━━━ 张华━━━━━ 查找指定父亲的所有儿子 父亲: 张德 有以下儿子! 张文张武 4.最短路径 假设有n个城市组成一个公路网(有向的),并用代价邻接矩阵表示该网络,编写一个指定城市v到其他各城市的最短路径的函数。 方法: 直接采用Dijkstra算法,略。 5.排序 对于对于输入的数字按从小到大和从大到小两种顺序进行排序,并显示中间排序过程。 [提示]可以采用快速排序方法进行数字的两种排序。 [C源程序] #include #defineMAX100 voiddisparr(); inta[MAX],n,m; voidcreatarr() { inti=0; printf("建立原始数序\n"); printf("\t元素个数: "); scanf("%d",&n); while(i { printf("\t第%d个元素: ",i+1); scanf("%d",&a[i]); i++; } } intcmp(intlval,intrval,intorder) { if(order==1) { if(lval (1); elsereturn(0); } else {if(lval>rval)return (1); elsereturn(0); } } voidquicksort(intx[],intl,intr,intorder) /*把x[l]至x[r]的元素进行快速排序*/ { inti=l,j=r,k,temp; temp=x[l]; while(i { while(i if(i { x[i]=x[j];i++; } while(i if(i { x[j]=x[i];j--; } } x[i]=temp; printf("\t(%d)",m++); for(k=0;k
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 实验 参考答案