课程she计.docx

上传人:b****5 文档编号:8725994 上传时间:2023-05-14 格式:DOCX 页数:44 大小:245.15KB
下载 相关 举报
课程she计.docx_第1页
第1页 / 共44页
课程she计.docx_第2页
第2页 / 共44页
课程she计.docx_第3页
第3页 / 共44页
课程she计.docx_第4页
第4页 / 共44页
课程she计.docx_第5页
第5页 / 共44页
课程she计.docx_第6页
第6页 / 共44页
课程she计.docx_第7页
第7页 / 共44页
课程she计.docx_第8页
第8页 / 共44页
课程she计.docx_第9页
第9页 / 共44页
课程she计.docx_第10页
第10页 / 共44页
课程she计.docx_第11页
第11页 / 共44页
课程she计.docx_第12页
第12页 / 共44页
课程she计.docx_第13页
第13页 / 共44页
课程she计.docx_第14页
第14页 / 共44页
课程she计.docx_第15页
第15页 / 共44页
课程she计.docx_第16页
第16页 / 共44页
课程she计.docx_第17页
第17页 / 共44页
课程she计.docx_第18页
第18页 / 共44页
课程she计.docx_第19页
第19页 / 共44页
课程she计.docx_第20页
第20页 / 共44页
亲,该文档总共44页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

课程she计.docx

《课程she计.docx》由会员分享,可在线阅读,更多相关《课程she计.docx(44页珍藏版)》请在冰点文库上搜索。

课程she计.docx

课程she计

1.设计1约瑟夫环问题

一、需求分析

1、利用单向循环链表存储结构模拟此过程,按照出列的顺序印出个人的编号,只适用于一个案例。

具体目标包括:

(1)实现单循环链表的初始化;

(2)理解约瑟夫环的定义,用循环找到每次报数人的序号;

(3)从单循环链表中删除节点,并判断链表空与非空的临界条件。

2、构造一个含有n个元素的单向循环链表

3、程序中,先输入总人数PN与初始密码SN,再输入输入n个正整数,作为这n个人的密码,接下来初始密码m。

4、测试数据PN=5SN=2,N个人的密码依次=14648。

出列为:

21354。

二、概要设计

1、函数功能在main函数中实现

voidmain(void)

{

intPN,SN,i;

LinkListL;

printf("请输入总人数PN,和出示密码SN:

");

scanf("%d%d",&PN,&SN);

inta[N];

a[0]=SN;//将a[0]保存为初始密码

printf("请输入%d个人各自所持的密码:

\n",PN);

for(i=1;i

scanf("%d",&a[i]);

//创建链表

CreatLinkList(&L,PN);

//报数删人,输出结果

printf("Result:

\n");

deldata(&L,PN,a);

}

2、程序包括两部分

(1)结点类型

(2)main函数实现约瑟夫环

三、详细设计

1、结点类型

typedefstructNode

{

intdata;//将这一圈人按从1~PN贴上序号

structNode*next;

}Node,*LinkList;

LinkListhead;

2、构建一个单循环链表算法

voidCreatLinkList(LinkList*L,intPN)

{

Node*p,*q;

inti;

(*L)=(LinkList)malloc(sizeof(Node));

p=(*L);

p->data=1;

for(i=2;i<=PN;i++)

{

q=(LinkList)malloc(sizeof(Node));

q->data=i;

p->next=q;

p=q;

}

p->next=(*L);

}

流程图:

 

 

2、程序主模块实现算法

从头结点开始,根据报数上限找到下一个出列人的序号,并读出该人的密码作为新的报数上限,从此节点的下一个节点开始进行新的查找。

取每次将要删除的人的密码,用于下次报数的上限.通过指针依次删除出列人相应的节点,直到该链表中无节点,退出循环。

四、运行结果及分析

1.调试分析

(1)进入程序后按提示输入程序初始数据回车后即可得到结果,输出结果表示依次出列人的序号,程序结束。

若输入过程中输入有误,程序直接结束。

算法时间复杂度正比于2n加上所有人的密码和。

(2)结果分析:

对一般数据与边界数据能输出正确结果;对错误数据能做出合适的反应。

2.测试结果

输入值不符合条件是:

 

五、总结

1.本程序比较简单,只有一个main函数,功能在main函数中实现,程序有待优化。

本次实验主要考察了对单循环链表的应用。

2.调试过程中,由于指针使用不当多次出现错误,对指针的设计还需要熟练掌握。

通过本次实验设计,巩固了演循环链表的知识。

附:

主要源代码

#include

#include

#defineN100

typedefstructNode

{

intdata;//将这一圈人按从1~PN贴上序号

structNode*next;

}Node,*LinkList;

voidCreatLinkList(LinkList*L,intPN)

{

Node*p,*q;

inti;

(*L)=(LinkList)malloc(sizeof(Node));

p=(*L);

p->data=1;

for(i=2;i<=PN;i++)

{

q=(LinkList)malloc(sizeof(Node));

q->data=i;

p->next=q;

p=q;

}

p->next=(*L);

}

voiddeldata(LinkList*L,intPN,inta[])

{

Node*p,*q;

intk;

intj=1;

inti=0;//取每次将要删除的人的密码,用于下次报数的上限

p=(*L);

for(;PN>=1;PN--)

{

k=1;

while(k!

=a[i])

{

p=p->next;

k++;

}

printf("第%d个出列的人的序号是%d,其密码是%d.\n",j,p->data,a[j]);

j++;

i=p->data;

p->data=p->next->data;

q=p->next;

p->next=p->next->next;

free(q);

}

}

voidmain(void)

{

intPN,SN,i;

LinkListL;

printf("请输入总人数PN,和出示密码SN:

");

scanf("%d%d",&PN,&SN);

inta[N];a[0]=SN;//将a[0]保存为初始密码

printf("请输入%d个人各自所持的密码:

\n",PN);

for(i=1;i

scanf("%d",&a[i]);

//创建链表

CreatLinkList(&L,PN);

//报数删人,输出结果

printf("Result:

\n");

deldata(&L,PN,a);

}

2.设计2前缀算术表达式转换及表达式计算

一、需求分析

1.问题描述:

算术表达式与二叉树之间存在着对应关系,编写把以前缀形式输入的合法算术表达式转换为中缀表达式,再转换为后缀表达式,并求表达式的值。

2.具体目标包括:

(1)把前缀表达式转换为中缀表达式;

(2)输出中缀表达式;

(3)把中缀表达式转换为后缀表达式;

(4)利用栈结构实现后缀表达式的求值;

3.定义栈的抽象数据类型:

ADTStack{

数据对象:

D={ai|ai∈ElemSet,i=1,2,...,n,n≥0}

数据关系:

R1={|ai-1,ai∈D,i=2,...,n}

基本操作:

InitStack(SqStack*S)

Push(SqStack*S,SNodeETypee)

Pop(SqStack*S,SNodeEType*e)

StackEmpty(SqStack*S)

}ADTStack

二、概要设计

1、程序包括两部分

(1)结点类型

typedefstructBiTNode

{

TElemTypedata;

structBiTNode*lchild,*rchild;

}BiTNode,*BiTree;

typedefstructNode

{SNodeETypedata;

structNode*next;

}SElemType;

typedefstructStack

{SElemType*base;

SElemType*top;

}SqStack;

typedefstructQNode{//队列

QElemTypedata;

structQNode*next;

}QNode,*QueuePtr;

typedefstruct{

QueuePtrfront;

QueuePtrrear;

}LinkQueue;

(2)基本操作的实现(见附:

主要源代码)

2、主要模块

三、详细设计(含主要算法的流程图)

1、删除栈顶元素并返回其值的算法

intPop(SqStack*S,SNodeEType*e)

int*e1;

if(S->top==S->base)

returnERROR;

*e=S->top->data;

e1=S->top;

S->top=S->top->next;

free(e1);

returnOK;}

2、BiTreeCreatBiTree(BiTreeT)

{//按前缀形式输入算术表达式,构造二叉链表表示的二叉树T

charch;scanf("%c",&ch);

switch(ch)

{

case'+':

;

case'-':

;

case'*':

;

case'/':

if(!

(T=(BiTNode*)malloc(sizeof(BiTNode))))

exit(OVERFLOW);

T->data=ch;

T->lchild=(BiTNode*)malloc(sizeof(BiTNode));

T->rchild=(BiTNode*)malloc(sizeof(BiTNode));

T->lchild=CreatBiTree(T->lchild);

T->rchild=CreatBiTree(T->rchild);break;

default:

if(!

(T=(BiTNode*)malloc(sizeof(BiTNode))))

exit(OVERFLOW);

T->data=ch;

T->lchild=NULL;

T->rchild=NULL;

}

returnT;

}

实现流程图:

 

 

四、运行结果及分析

五、总结

1、调试过程中遇到的问题:

在调试过程中,插入新结点时,结点指针指的位置不对,导致添加后的二叉树不符合;在输出二叉树时由于输出算法错误导致输出不正确,经过网上找了一些材料,最后输出正确。

2、编写程序时必须注意一些细小的问题,对临界问题考虑全面,养成良好的编程习惯。

熟练掌握算术表达式与二叉树的性质与算法,巩固算术表达式之间的转换算法以及后序遍历的递归算法实现树的输出算法。

附:

主要源代码

#include

#include

#include

#defineMAXSIZE100

#defineTElemTypechar

#defineQElemTypechar

#defineSNodeETypefloat

#defineOK1

#defineOVERFLOW0

#defineTRUE1

#defineFALSE0

#defineERROR0

#definestatusint

typedefstructBiTNode

{

TElemTypedata;

structBiTNode*lchild,*rchild;

}BiTNode,*BiTree;

typedefstructNode

{SNodeETypedata;

structNode*next;

}SElemType;

typedefstructStack

{SElemType*base;

SElemType*top;

}SqStack;

typedefstructQNode

{

QElemTypedata;

structQNode*next;

}QNode,*QueuePtr;

typedefstruct

{

QueuePtrfront;

QueuePtrrear;

}LinkQueue;

statusInitQueue(LinkQueue*Q)

{//构造一个空队列Q

if(!

(Q->rear=(QueuePtr)malloc(sizeof(QNode))))

exit(OVERFLOW);

Q->front=Q->rear;

Q->front->next=NULL;

returnOK;}

statusEnQueue(LinkQueue*Q,QElemTypee)

{//插入以e为Q的新的队尾元素

QueuePtrp;

if(!

(p=(QueuePtr)malloc(sizeof(QNode))))

exit(OVERFLOW);

p->data=e;p->next=NULL;

Q->rear->next=p;Q->rear=p;

returnOK;

}

statusDeQueue(LinkQueue*Q,QElemType*e)

{//删除Q的队头元素,用e返回其值

QueuePtrp;

p=Q->front->next;*e=p->data;

Q->front->next=p->next;

if(Q->rear==p)Q->rear=Q->front;

free(p);

returnOK;

}

statusInitStack(SqStack*S)

{//构造一个空栈S

S->base=(SElemType*)malloc(sizeof(SElemType));

if(!

S->base)

exit(OVERFLOW);//存储分配失败

S->top=S->base;

returnOK;

}//InitStack

voidPush(SqStack*S,SNodeETypee)

{//插入元素e为新的栈顶元素

SElemType*e1;

e1=(SElemType*)malloc(sizeof(SElemType));

e1->next=S->top;e1->data=e;S->top=e1;}//Push

statusPop(SqStack*S,SNodeEType*e)

{//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR

SElemType*e1;

if(S->top==S->base)

returnERROR;

*e=S->top->data;

e1=S->top;

S->top=S->top->next;

free(e1);

returnOK;

}

statusStackEmpty(SqStack*S)

{//判断栈S是否为空,若不空返回TRUE,否者返回FALSE

if(S->top==S->base)

returnTRUE;

else

returnFALSE;

}

BiTreeCreatBiTree(BiTreeT)

{//按前缀形式输入算术表达式

//构造二叉链表表示的二叉树T

charch;

scanf("%c",&ch);

switch(ch)

{

case'+':

;

case'-':

;

case'*':

;

case'/':

if(!

(T=(BiTNode*)malloc(sizeof(BiTNode))))

exit(OVERFLOW);

T->data=ch;

T->lchild=(BiTNode*)malloc(sizeof(BiTNode));

T->rchild=(BiTNode*)malloc(sizeof(BiTNode));

T->lchild=CreatBiTree(T->lchild);

T->rchild=CreatBiTree(T->rchild);

break;

default:

if(!

(T=(BiTNode*)malloc(sizeof(BiTNode))))

exit(OVERFLOW);

T->data=ch;T->lchild=NULL;

T->rchild=NULL;

};returnT;

}

statusInOrderT(BiTreeT)

{//中序遍历二叉树

if(T){InOrderT(T->lchild);

printf("%c",T->data);

InOrderT(T->rchild);

}

returnOK;

}

statusAfterOrderT(BiTreeT,LinkQueue*Q)

{

chare;//后序遍历二叉树

if(T){AfterOrderT(T->lchild,Q);

AfterOrderT(T->rchild,Q);

printf("%c",T->data);e=T->data;

EnQueue(Q,e);

}returnOK;

}

statusJisuan(SNodeEType*e1,SNodeETypee2,charch)

{switch(ch)

{

case'+':

*e1=*e1+e2;break;

case'-':

*e1=e2-*e1;break;

case'*':

*e1=*e1*e2;break;

case'/':

*e1=e2/(*e1);break;

}

returnOK;

}

statusOper(LinkQueue*Q)

{SqStack*S;charch;intsag=1;

SNodeETypee1,e2,e;

if(!

(S=(SqStack*)malloc(sizeof(SqStack))))

exit(OVERFLOW);

while(Q->front!

=Q->rear)

{DeQueue(Q,&ch);

switch(ch)

{case'+':

;

case'-':

;

case'*':

;

case'/':

Pop(S,&e1);Pop(S,&e2);

Jisuan(&e1,e2,ch);

Push(S,e1);break;

default:

if(sag==1)

{printf("(有几个变量?

按行输入)为变量赋值:

");sag=0;}

scanf("%f",&e);Push(S,e);}}Pop(S,&e1);

printf("结果为:

%3f\n",e1);returnOK;}

voidmain()

{BiTNode*T;LinkQueue*Q;

Q=(LinkQueue*)malloc(sizeof(LinkQueue));

InitQueue(Q);

T=(BiTNode*)malloc(sizeof(BiTNode));

T->lchild=NULL;T->rchild=NULL;

printf("按前缀形式输入算术表达式\n");

printf("请输入前缀表达式:

");

T->lchild=CreatBiTree(T->lchild);

printf("中序表达式:

");

InOrderT(T->lchild);printf("\n");

printf("后序表达式:

");

AfterOrderT(T->lchild,Q);

printf("\n");Oper(Q);}

3.设计3矩阵乘法和加法算法的应用

一、需求分析

1.问题描述:

设A=,给定A上的关系R为R={,,,},求R的传递闭包。

2.具体目标:

设定一个关系R(矩阵),执行本程序,自动求出R的传递闭包。

二、概要设计

1.函数功能在main函数中实现。

函数调用关系:

在Main()中调用work(),实现程序的主要功能。

intmain(intargc,char*argv[])

{

intR[10][10];

intn,i,j;

printf("请输入关系矩阵的维数\n");

scanf("%d",&n);

printf("请输入关系矩阵R\n");

for(i=0;i

for(j=0;j

scanf("%d",&R[i][j]);

}

}

work(R,n);

return0;

}

2.算法描述:

在集合X上的二元关系R的传递闭包是包含R的X上的最小的传递关系。

R的传递闭包在数字图像处理的图像和视觉基础、图的连通性描述等方面都是基本概念。

一般用B表示定义在具有n个元素的集合X上关系R的n×n二值矩阵,则传递闭包的矩阵B+=B+B2+B3+……+(B)n 式中矩阵运算时所有乘法都用逻辑与代替,所有加法都用逻辑或代替。

上式中的操作次序为B,B(B),B(BB),B(BBB),以此类推。

所以在运算的每一步我们只需简单地把现有结果乘以B,完成矩阵的n次乘法即可。

三、详细设计

1.主程序(实现主要功能)

intmain(intargc,char*argv[])

{

intR[10][10];

intn,i,j;

printf("请输入关系矩阵的维数\n");

scanf("%d",&n);

printf("请输入关系矩阵R\n");

for(i=0;i

for(j=0;j

scanf("%d",&R[i][j]);

}

}

work(R,n);

return0;

}

2.voidwork(intR[10][10],intn)

{

求矩阵R[][]的传递闭包;

将输入的矩阵R赋值给矩阵M;

用M的行乘以R的列得到Rn,并将Rn赋值给M;

最后将R1R2R3R4…….Rn相加的结果赋给R;

将矩阵R[][]中非0元素置换为1;

输出传递闭包;

}

四、运行结果及分析

正确的运行结果:

五、总结

编写程序过程中,由于对矩阵相乘的性质和算法掌握不牢固,所以在程序运行遇到了一些问题。

在集合X上的二元关系R的传递闭包是包含R的X上的最小的传递关系。

R的传递闭包在数字图像处理的图像和视觉基础、图的连通性描述等方面都是基本概念。

这些都是本实验设计所需的一些基本知识,但是由于学习是掌握不牢固,拿到题目时只能先巩固基础知识,这样就花费了不少时间。

附:

主要源代码

//#include"stdafx.h"

#include"stdio.h"

#include"stdlib.h"

voidwork(intR[10][10],intn){//求矩阵R[][]的传递闭包

inti,j,k,m;

intM[10][10];

inta=0;

for(i=0;i

for(j=0;j

M[i][j]=R[i][j];

}

for(m=1;m

for(i=0;i

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2