搜档网
当前位置:搜档网 › (盐城工学院数据结构课程设计)栈的应用表达式求值

(盐城工学院数据结构课程设计)栈的应用表达式求值

(盐城工学院数据结构课程设计)栈的应用表达式求值
(盐城工学院数据结构课程设计)栈的应用表达式求值

数据结构课程设计报告

栈的应用:表达式求值的设计

专业 学生姓名 班级 学

指导教师 徐燕萍 完成日期

目录

1设计内容 (1)

2设计分析

2.1系统需求分析 (1)

2.1.1系统目标 (1)

2.1.2主体功能 (1)

2.2系统概要设计 (1)

2.2.1系统的功能模块划分 (1)

2.2.2系统流程图 (2)

3设计实践

3.1基本分析 (3)

3.2中缀表达式求值 (4)

3.3后缀表达式求值 (5)

3.4中缀表达式转换成后缀表达式 (6)

4测试方法

4.1基本测试 (7)

4.2拓展测试 (7)

4.3容错测试 (8)

5程序运行效果 (7)

6设计心得 (8)

7附录:源代码 (10)

栈的应用:表达式求值的设计

1 设计内容

设计一个表达式求值的程序。该程序必须可以接受包含(,),+,-,*,/,%,和^(求幂运算符,a^b=a b)的中缀表达式,并求出结果。如果表达式正确,则输出表达式的结果;如果表达式非法,则输出错误信息。

2 设计分析

2.1系统需求分析

2.1.1系统目标

利用栈设计一个程序,该程序能够用于表达式求值,程序将读入的中缀表达式转换为后缀表达式,然后读取后缀表达式,输出结果。

输入要求:程序从“input.txt”文件中读取信息,在这个文件中如果有多个中缀表达式,则每个表达式独占一行,程序的读取操作在文件的结尾处停止。

输出要求:对于每一个表达式,将其结果放在“output.txt”文件的每一行中。这些结果可能是值(精确到小数点后两位),也可能是错误信息“ERROR IN INFIX NOTATION”。

2.1.2 主体功能

能够处理以字符序列的形式输入的不含变量的实数表达式,正确处理负数与小数,判断表达式是否语法正确(包含分母不能为零的情况),正确实现对算术四则混合运算表达式的求值,能够将计算中遇到的问题和结果以文件的形式予以存储。

2.2系统概要设计

2.2.1系统的功能模块划分

1.判断操作数的函数isnum()

判断当前所指字符是否属于数字,是就返回‘1’,不是就返回‘0’。

2.求运算符优先级函数priority()

为了方便判断运算符优先级,先利用switch函数将不同的运算符返回不同的整型数字,在根据数字的大小判断优先级。‘+’,‘-’优先级相同,返回数字相同,‘*’,‘/’也是。

3.表达式求值函数infix_value()

此函数是直接按照设计思路完成问题要求的函数,其中要调用到判断操作符的函数isnum()和求运算符优先级的函数priority()。循环结束弹出栈2的数值,并返回。

4.主函数main()

定义一个数组存储表达式整个字符串,将返回的数值直接赋值到浮点型的result,输出result。

5.两个栈的函数设计:

栈的初始化函数charInit_SeqStack()

Init_SeqStack()

栈判空 Empty_SeqStack()

char Empty_SeqStack()

入栈函数 Push_SeqStack()

charPush_SeqStack()

出栈函数 Pop_SeqStack()

charPop_SeqStack()

取栈顶函数 GetTop_SeqStack()

charGetTop_SeqStack()

销毁栈 Destory_SeqStack()

charDestory_SeqStack()

2.2.2系统流程图

图1 系统流程图

3设计实践

3.1基本分析

在计算机中,算术表达式的计算往往是通过使用栈来实现的。所以,本表达式求值程序的最主要的数据结构就是栈。可以使用栈来存储输入表达式的操作符和操作数。

输入的表达式是由操作数和运算符以及改变运算次序的圆括号连接而成的式子。

表达式求值是高级语言编译中的一个基本问题,是栈的典型应用实例。任何一个表达式都是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。操作数既可以是常数,也可以是被说明为变量或常量的标识符;运算符可以分为算术运算符、关系运算符和逻辑运算符三类;基本界限符有左右括号和表达式结束符等。

3.2中缀表达式求值

中缀表达式:每个二目运算符在两个运算量的中间,假设操作数是整型常数,运算符只含加、减、乘、除等四种运算符,界限符有左右括号和表达式起始、结束符“#”,如:#(7+15)*(23-28/4)#。要对一个简单的算术表达式求值,首先要了解算术四则运算的规则,即:

(1) 从左到右;

(2) 先乘除,后加减;

(3) 先括号内,后括号外。

运算符和界限符可统称为算符,它们构成的集合命名为OPS。根据上述三条运算规则,在运算过程中,任意两个前后相继出现的算符θ1和θ2之间的优先关系必为下面三种关系之一:

θ1<θ2,θ1的优先权低于θ2。

θ1=θ2,θ1的优先权等于θ2。

θ1>θ2,θ1的优先权高于θ2。

实现算符优先算法时需要使用两个工作栈:一个称作operator,用以存放运算符;另一个称作operand,用以存放操作数或运算的中间结果。算法的基本过程如下:

首先初始化操作数栈operand和运算符栈operator,并将表达式起始符“#”压入运算符栈;

依次读入表达式中的每个字符,若是操作数则直接进入操作数栈operand,若是运算符,则与运算符栈operator的栈顶运算符进行优先权比较,并做如下处理:

(1) 若栈顶运算符的优先级低于刚读入的运算符,则让刚读入的运算符进operator栈;

(2) 若栈顶运算符的优先级高于刚读入的运算符,则将栈顶运算符退栈,送入θ,同时将操作数栈operand退栈两次,得到两个操作数a、b,对a、b进行θ运算后,将运算结果作为中间结果推入operand栈;

(3) 若栈顶运算符的优先级与刚读入的运算符的优先级相同,说明左右括号相遇,只需将栈顶运算符(左括号)退栈即可。operator栈的栈顶元素和当前读入的字符均为“#”时,说明表达式起始符“#”与表达式结束符“#”相遇,整个表达式求解结束。

int ExpEvaluation()

{ /*读入一个简单算术表达式并计算其值。*/

InitStack(&operand); InitStack(&operator);

PushStack(&operator, ’#’);

printf(″\n\n Please input an expression (Ending with #) :″);

ch=getchar(); /*读入表达式中的一个字符*/

while(ch!=‘#’||GetTop(operator)!=‘#’)

{ if(!In(ch, OPS)) /*判断ch是否运算符*/

{ a=GetNumber(&ch); /* 用ch逐个读入操作数的各位数

码,并转化为十进制数a */

PushStack(&operand,a);}

else

switch(Compare(GetTop(operator),ch))

{ case ′<′: PushStack(&operator, ch);

ch=getchar(); break;

case ′=′: Pop Stack(&operator,&x);

ch=getchar(); break;

case ′>′: PopStack(&operator, &op);

PopStack(&operand, &b);

PopStack(&operand, &a);

v=Execute(a,op,b);

PushStack(&operand,v);

break;

}

}

v=GetTop(operand);

return(v);

}

为了处理方便,编译程序常把中缀表达式首先转换成等价的后缀表

达式,后缀表达式的运算符在运算对象之后。在后缀表达式中,不再引

入括号,所有的计算按运算符出现的顺序,严格从左向右进行,而不用

再考虑运算规则和级别。中缀表达式“(a+b*c)-d/e”的后缀表达式

为:“abc*+de/-”。

3.3后缀表达式求值

计算一个后缀表达式,算法上比计算一个中缀表达式简单的多。这

是因为表达式中即无括号又无优先级的约束。具体做法:只使用一个对

象栈,当从左向右扫描表达式时,每遇到一个操作数就送入栈中保存,

每遇到一个运算符就从栈中取出两个操作数进行当前的计算,然后把结

果再入栈,直到整个表达式结束,这时送入栈顶的值就是结果。

下面是后缀表达式求值的算法,在下面的算法中假设,每个表达式

是合乎语法的,并且假设后缀表达式已被存入一个足够大的字符数组A

中,且以‘#’为结束字符,为了简化问题,限定运算数的位数仅为一

位且忽略了数字字符串与相对应的数据之间的转换问题。

double calcul_exp(char *A) /*本函数返回由后缀表达式A表示的表达式运算结果*/

{ SeqStarck s;

ch=*A++ ; InitStack(s);

while(ch!= ’#’ )

{ if(ch!=运算符) PushStack(s, ch);

else

{ PopStack(s, &a);

PopStack(s, &b); /*取出两个运算量*/

switch(ch)

{ case ch==’+’: c=a+b; break ;

case ch==’-’: c=a-b; break ;

case ch==’*’: c=a*b; break ;

case ch==’/ ’: c=a/b; break ;

case ch==’%’:c=a%b; break ;

}

PushStack (s, c) ;

}

ch=*A++ ;

}

PopStack(s, result) ;

return result ;

}

3.4中缀表达式转换成后缀表达式

将中缀表达式转化为后缀表达式和前述对中缀表达式求值的方法完全类似,但只需要运算符栈,遇到运算对象时直接放后缀表达式的存储区,假设中缀表达式本身合法且在字符数组A中,转换后的后缀表达式存储在字符数组B中。具体做法:遇到运算对象顺序向存储后缀表达式的B数组中存放,遇到运算符时类似于中缀表达式求值时对运算符的处理过程,但运算符出栈后不是进行相应的运算,而是将其送入B中存放。读者不难写出算法,在此不在赘述。

程序的整体算法分两步:

第一步,从”input.txt”文件中读取中缀表达式,并应用运算符栈OpHolder把中缀表达式转换为后缀表达式,将输出结果存放在一个temp 文件中。

第二步,从temp文件中读取中缀表达式,并应用操作栈Operands

计算后缀表达式结果,将结果输出到”output.txt”文件中。

4测试方法

设计针对程序的input.txt文件,并将运行结果与期望测试进行比较。

5 程序运行效果

5.1 基本测试:

在input文件中输入表达式如下图2:则输出结果如下图3:

图2 图3

图4

5.2扩展测试:

在input文件中输入表达式如下图5:则输出结果如下图6:

图5 图6

5.3容错测试:

在input文件中输入表达式如下图7:则输出结果如下图8:

图7 图8

6 设计心得

通过此次的课程设计,巩固和加深了我对栈、队列、字符串等理论知识的理解;掌握现实复杂问题的分析建模和解决方法(;提高利用计

算机分析解决综合性实际问题的基本能力。

在细节问题的分析上,较以往有了很大的提高。在寻求最优解的问题上,也能够找到多种解决方案来使自己的程序收放自如。如,在处理实数的问题上,我采用的是每取得一个字符,就立刻对此字符进行处理的方法。其实,我们可以用一个字符数组,来存储连接着的一系列数字字符,然后再通过atof函数,直接得到字符数组中所存储的数字。再如,对负数问题的处理上,我最初的想法是通过一个标志mark来记录前面的字符是否是负号(或减号),再在后面取到除符号外的数字时,选择是否添加负号。另外,与其他人不同的是,在我的课程设计中,Compare ()函数与其他有着很大的区别。通常情况下,同学们参照课本,都会采用占用7*7=49个空间的数组来分别存储对应两个字符的优先级符号,并对两个字符进行预算之后得到数组中的位置。虽然7*7的数组所占的空间并不是非常大,但在我看来这也是一种浪费,并且空间的浪费并没有换回时间一定的节省。因此,我采用了一种常规的思路。将各种运算符按照数学逻辑上的优先顺序进行排序,并得到两个字符之间的优先级关系。这样一来,我们将不再需要那7*7的数组,且时间复杂度并不大幅增涨。

在这个课程设计中,运用到的数据结构的知识主要是栈的知识。栈在各种软件系统中,应用非常广泛。栈的的存储特性(LIFO先进后出),使得在用栈来编程时,思路清晰明了。在使用递归算法时,栈也是一种很好的选择。

此外,这次的课程设计进一步加强了我们运用C语言进行编程,调试,处理问题的能力,加深了我们对算法及数据结构的认识。同时我也意识到,开发程序的早期计划要做的充分,以免出现程序完成后发现不足而带来的修改麻烦。虽然这只是一个小小的软件,但对我们之后的影响确实很大的。

7 附:源程序清单

#include

#include

#include

int PrintError = 0;

/*全局变量,0代表正常,1代表表达式出错*/

/*char类型链表式堆栈,用来存放运算符号,以及用在中缀表达式转换等时候*/ typedef struct Node *PtrToNode;

typedef PtrToNode Stack;

int IsEmpty(Stack S);

void MakeEmpty(Stack S);

void Push(char X,Stack S);

char Top(Stack S);

void Pop(Stack S);

typedef struct Node{

char Element;

PtrToNode Next;

};

/*float类型链表式堆栈,用来存放操作数*/

typedef struct FNode *Ptr_Fn;

typedef Ptr_Fn FStack;

int FisEmpty(FStack S);

void FPush(float X,FStack S);

float FTop(FStack S);

void FPop(FStack S);

typedef struct FNode{

float Element;

Ptr_Fn Next;

};

void ConvertToPost(FILE *In, Stack Whereat,FILE *Temp);

void Reverse(Stack Rev);

void Calculate(FILE *Change, Stack Whereat,FILE *Temp);

/******主函数******/

int main()

{

FILE *InputFile, *OutputFile,*Temp; /*初始化变量*/

Stack Whereat;

char sample;

InputFile = fopen("Input.txt","r"); /*打开文件*/

OutputFile = fopen("Output.txt","w");

Whereat = malloc(sizeof(struct Node)); /*给Whereat分配空间*/ Whereat->Next = NULL;

if (!InputFile || !OutputFile) { /*错误处理*/ printf("intput or output file(s) do not exist.\n");

return(1);

}

sample = getc(InputFile);

while ( sample != EOF){

Temp = fopen("Temp.txt","w+"); /*生成Temp文件*/

ungetc(sample,InputFile); /* put back sample字符*/

ConvertToPost(InputFile,Whereat,Temp); /*中缀变后缀*/

if (PrintError){ /*错误处理*/

fprintf(OutputFile,"Error in infix notation.");

fscanf(InputFile,"\n",&sample);

PrintError = 0;

}

else if (IsEmpty(Whereat) == 1){ /*跳过在input文件中的空格*/

}

else if (IsEmpty(Whereat) != 1){

Reverse(Whereat);

if (Top(Whereat) == 'B'){ /*错误处理,*/

/*A表示操作数B表示运算符*/ PrintError = 1; /*后缀表达式第一个元素应是操作数而不是运算符号*/

}

fclose(Temp);

Temp = fopen("Temp.txt","r+");

Calculate(OutputFile, Whereat,Temp); /*计算结果*/

}

fclose(Temp);

MakeEmpty(Whereat); /* 清空Whereat用来处理下一行*/

putc('\n',OutputFile); /* 在输出文件中换行*/

sample = getc(InputFile);

} /* While循环结束*/

free(Whereat);

fclose(InputFile);

fclose(OutputFile);

remove("Temp.txt"); /* 删除Temp.txt*/ return 1;

}

/******检查堆栈是否为空******/

int IsEmpty(Stack S)

{

return(S->Next==NULL);

}

/******检查float堆栈是否为空******/

int FIsEmpty(FStack S)

{

return(S->Next==NULL);

}

/******弹出栈顶元素******/

void Pop(Stack S)

{

PtrToNode FirstCell;

if (IsEmpty(S))

perror("Empty Stack");

else{

FirstCell = S->Next;

S->Next = S->Next->Next;

free(FirstCell);

}

}

/******弹出float栈顶元素******/

void FPop(FStack S)

{

Ptr_Fn FirstCell;

if (FIsEmpty(S))

perror("Empty Stack");

else{

FirstCell = S->Next;

S->Next = S->Next->Next;

free(FirstCell);

}

}

/******将堆栈置空******/

void MakeEmpty(Stack S)

{

if (S == NULL)

perror("Must use Createstack first");

else

while (!IsEmpty(S))

Pop(S);

}

/******将float堆栈置空******/

void FMakeEmpty(FStack S)

{

if (S == NULL)

perror("Must use Createstack first");

else

while (!IsEmpty(S))

Pop(S);

}

/******元素进栈******/

void Push(char X, Stack S)

{

PtrToNode TmpCell;

TmpCell = (PtrToNode)malloc(sizeof(struct Node));

if (TmpCell == NULL)

perror("Out of Space!");

else{

TmpCell->Element = X;

TmpCell->Next = S->Next;

S->Next = TmpCell;

}

}

/******float元素进栈******/

void FPush(float X, FStack S)

{

Ptr_Fn TmpCell;

TmpCell = (Ptr_Fn)malloc(sizeof(struct FNode));

if (TmpCell == NULL)

perror("Out of Space!");

else{

TmpCell->Element = X;

TmpCell->Next = S->Next;

S->Next = TmpCell;

}

}

/******返回栈顶元素******/

char Top(Stack S)

{

if (!IsEmpty(S))

return S->Next->Element;

perror("Empty Stack");

exit(1);

return 0;

}

/******返回float栈顶元素******/

float FTop(FStack S)

{

if (!FIsEmpty(S))

return S->Next->Element;

perror("Empty Stack");

exit(1);

return 0;

}

/******将堆栈元素倒置******/

void Reverse(Stack Rev)

{

Stack Tempstack;

Tempstack = malloc(sizeof(struct Node));

Tempstack->Next = NULL;

while (!IsEmpty(Rev)){

Push(Top(Rev),Tempstack); /*将元素压栈到一个临时堆栈*/

Pop(Rev);

}

Rev->Next = Tempstack->Next; /*指向新的堆栈*/

}

/*******

Whereat 说明:

Whereat 记录了操作数和运算符号的位置,用A和B区分。A = operand, B = operator. (例如1+2转换成12+,在whereat中的形式应该是AAB)

OpHolder说明:

Char类型的堆栈Opholder用来保存运算符号。

******/

/******将中缀表带式转换为后缀表达式******/

void ConvertToPost(FILE *In, Stack Whereat, FILE *Temp)

{

Stack OpHolder;

char holder;

char lastseen;

int digitcounter = 0; /*操作数的计数器*/

OpHolder = malloc(sizeof(struct Node)); /*初始化*/

OpHolder->Next = NULL;

holder=getc(In);

lastseen = '@'; /*用来防止输入格式错误,例如两个小数点*/ putc(' ',Temp);

while ((holder !='\n') && (holder != EOF)){

if (holder == ' '){

digitcounter = 0;

}

else if ( IsOperator(holder) == -1){ /*如果holder不是操作数或运算符号*/

PrintError = 1;

}

else if (IsOperator(holder)==0){

if ((lastseen == holder) && (lastseen == '.')){ /*错误处理*/

PrintError = 1;

}

else

lastseen = holder;

if (digitcounter == 0){

Push('A',Whereat); /*进栈*/

digitcounter++; /*计数器加一*/

putc(' ',Temp);

}

putc(holder,Temp);

}

else{

digitcounter = 0;

if ((lastseen == holder) && (lastseen != '(') && (lastseen != ')')) /*"("情况特殊对待*/

PrintError = 1;

else

lastseen = holder;

if(IsEmpty(OpHolder)==1){ /*当OpHolder为空*/

Push(holder,OpHolder);

}

else if(OperatorValue(Top(OpHolder)) == 6){ /*OpHolder是"("的情况*/ if(OperatorValue(holder)==5)

Pop(OpHolder);

else

Push(holder,OpHolder);

}

else if(OperatorValue(holder) == 6){

Push(holder,OpHolder);

}

else if(OperatorValue(holder) == 5){ /* OpHolder是" )"的情况*/

while ((IsEmpty(OpHolder) != 1) && (OperatorValue(Top(OpHolder)) != 6))

{

putc(' ',Temp);

Push('B',Whereat);

putc(Top(OpHolder),Temp);

Pop(OpHolder);

}

if (IsEmpty(OpHolder) == 1){ /*错误处理,括号不匹配*/

PrintError = 1;

}

else

Pop(OpHolder);

}

else if((OperatorValue(holder) == OperatorValue(Top(OpHolder)))

&& (OperatorValue(holder) == 3)){ /*幂运算情况*/

Push(holder,OpHolder);

}

else if((OperatorValue(holder) < OperatorValue(Top(OpHolder)))

&& OperatorValue(Top(OpHolder)) == 3){ /*幂运算情况*/

putc(' ',Temp);

Push('B',Whereat);

putc(Top(OpHolder),Temp);

Pop(OpHolder);

while((IsEmpty(OpHolder) != 1) && (OperatorValue(Top(OpHolder)) == 3))

{

Push('B',Whereat);

putc(' ',Temp);

putc(Top(OpHolder),Temp);

Pop(OpHolder);

}

Push(holder,OpHolder);

}

/******

如果当前运算符号的优先级小于或者等于堆栈中的运算符号的优先级,则将其放入temp中,并且将堆栈中的运算符号出栈,放入temp中,直到堆栈为空或者优先级小于堆栈顶元素的优先级

******/

else if(OperatorValue(Top(OpHolder)) >= OperatorValue(holder)){

while((IsEmpty(OpHolder) != 1)

&& (OperatorValue(Top(OpHolder)) >= OperatorValue(holder))

&& (OperatorValue(Top(OpHolder))!=6))

{

putc(' ',Temp);

putc(Top(OpHolder),Temp);

Push('B',Whereat);

Pop(OpHolder);

}

Push(holder,OpHolder);

}

else if(OperatorValue(Top(OpHolder)) < OperatorValue(holder)){

/******

如果当前运算符号的优先级大于堆栈中的运算符号的优先级,则将其压入堆栈中

******/

Push(holder,OpHolder);

}

}

holder=getc(In);

} /* While循环结束*/

while(IsEmpty(OpHolder)!=1){

/******

最后如果堆栈中还有运算符号,则一并放到temp中

******/

Push('B',Whereat);

putc(' ',Temp);

putc(Top(OpHolder),Temp);

Pop(OpHolder);

}

MakeEmpty(OpHolder);

free(OpHolder);

}

/******判断类型,1为运算符号,0为操作数,-1为错误******/

int IsOperator(char ToCompare)

{

if (ToCompare == '(' || ToCompare == ')'|| ToCompare == '+' || ToCompare == '-' || ToCompare == '*'|| ToCompare == '/' || ToCompare == '^'|| ToCompare == '%') {

return 1;

}

else if (ToCompare == '1' || ToCompare == '2'|| ToCompare == '3'

|| ToCompare == '4' || ToCompare == '5'|| ToCompare == '6'

|| ToCompare == '7'|| ToCompare == '8' || ToCompare == '9'

|| ToCompare == '0'|| ToCompare == '.')

{

return 0;

}

else{

return -1;

}

数据结构课程设计

1.一元稀疏多项式计算器 [问题描述] 设计一个一元稀疏多项式简单计算器。 [基本要求] 输入并建立多项式; 输出多项式,输出形式为整数序列:n, c1, e1, c2, e2,……, cn, en ,其中n是多项式的项数,ci, ei分别是第i项的系数和指数,序列按指数降序排序; 多项式a和b相加,建立多项式a+b; 多项式a和b相减,建立多项式a-b; [测试数据] (2x+5x8-3.1x11)+(7-5x8+11x9)=(-3.1x11+11x9+2x+7) (6x-3-x+4.4x2-1.2x9)-(-6x-3+5.4x2-x2+7.8x15)=(-7.8x15-1.2x9-x+12x-3) (1+x+x2+x3+x4+x5)+(-x3-x4)=(x5+x2+x+1) (x+x3)+(-x-x3)=0 (x+x2+x3)+0=(x3+x2+x) [实现提示] 用带头结点的单链表存储多项式,多项式的项数存放在头结点中。 2.背包问题的求解 [问题描述] 假设有一个能装入总体积为T的背包和n件体积分别为w1, w2, …,wn的物品,能否从n件物品中挑选若干件恰好装满背包,即使w1+w2+…+wn=T,要求找出所有满足上述条件的解。例如:当T=10,各件物品的体积为{1,8,4,3,5,2}时,可找到下列4组解:(1,4,3,2)、(1,4,5)、(8,2)、(3,5,2) [实现提示] 可利用回溯法的设计思想来解决背包问题。首先,将物品排成一列,然后顺序选取物品转入背包,假设已选取了前i件物品之后背包还没有装满,则继续选取第i+1件物品,若该件物品“太大”不能装入,则弃之而继续选取下一件,直至背包装满为止。但如果在剩余的物品中找不到合适的物品以填满背包,则说明“刚刚”装入背包的那件物品“不合适”,应将它取出“弃之一边”,继续再从“它之后”的物品中选取,如此重复,直至求得满足条件的解,或者无解。 由于回溯求解的规则是“后进先出”因此自然要用到栈。 3.完全二叉树判断 用一个二叉链表存储的二叉树,判断其是否是完全二叉树。 4.最小生成树求解(1人) 任意创建一个图,利用克鲁斯卡尔算法,求出该图的最小生成树。 5.最小生成树求解(1人) 任意创建一个图,利用普里姆算法,求出该图的最小生成树。 6.树状显示二叉树 编写函数displaytree(二叉树的根指针,数据值宽度,屏幕的宽度)输出树的直观示意图。输出的二叉树是垂直打印的,同层的节点在同一行上。 [问题描述] 假设数据宽度datawidth=2,而屏幕宽度screenwidth为64=26,假设节点的输出位置用 (层号,须打印的空格数)来界定。 第0层:根在(0,32)处输出;

数据结构算术表达式求值实验报告

软件技术基础实验报告 实验名称:表达式计算器 系别:通信工程 年级: 班级: 学生学号: 学生姓名: 《数据结构》课程设计报告 题目简易计算表达式的演示 【题目要求】 要求:实现基本表达式计算的功能 输入:数学表达式,表达式由整数和“+”、“-”、“×”、“/”、“(”、“)”组成输出:表达式的值 基本操作:键入表达式,开始计算,计算过程和结果记录在文档中 难点:括号的处理、乘除的优先级高于加减

1.前言 在计算机中,算术表达式由常量、变量、运算符和括号组成。由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进行。因而在程序设计时,借助栈实现。 算法输入:一个算术表达式,由常量、变量、运算符和括号组成(以字符串形式输入)。为简化,规定操作数只能为正整数,操作符为+、-*、/、=,用#表示结束。 算法输出:表达式运算结果。 算法要点:设置运算符栈和运算数栈辅助分析算符优先关系。在读入表达式的字符序列的同时,完成运算符和运算数的识别处理,以及相应运算。 2.概要设计 2.1 数据结构设计 任何一个表达式都是由操作符,运算符和界限符组成的。我们分别用顺序栈来寄存表达式的操作数和运算符。栈是限定于紧仅在表尾进行插入或删除操作的线性表。顺序栈的存储结构是利用一组连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针top 指示栈顶元素在顺序栈中的位置,base 为栈底指针,在顺序栈中,它始终指向栈底,即top=base 可作为栈空的标记,每当插入新的栈顶元素时,指针top 增1,删除栈顶元素时,指针top 减1。 2.2 算法设计 为了实现算符优先算法。可以使用两个工作栈。一个称为OPTR ,用以寄存运算符,另一个称做OPND ,用以寄存操作数或运算结果。 1.首先置操作数栈为空栈,表达式起始符”#”为运算符栈的栈底元素; 2.依次读入表达式,若是操作符即进OPND 栈,若是运算符则和OPTR 栈的栈顶运算符比较优先权后作相应的操作,直至整个表达式求值完毕(即OPTR 栈的栈顶元素和当前读入的字符均为”#”)。 2.3 ADT 描述 ADT Stack{ 数据对象:D={ i a |i a ∈ElemSet,i=1,2,…,n, n ≧0} 数据对象:R1={< 1 ,-i i a a >| 1-i a ,D a i ∈,i=2,…,n}

利用栈实现c语言计算器

栈的应用:C实现简单计算器(表达式的计算) 作为栈的著名应用,表达式的计算可以用下面方法实现: 首先建立两个栈,操作数栈NUM_S和运算符栈OPR_S。 其中,操作数栈用来存储表达式中的操作数;运算符栈用来存储表达式中的运算符。可以用字符‘=’来表示表达式结束符。 自左至右的扫描待处理的表达式,并假设当前扫描到的符号为W,根据不同的符号W 做如下不同的处理: 1.若W为操作数,则将W压入操作数栈NUM_S,且继续扫描下一个字符; 2.若W为运算符,则根据运算符的性质做相应的处理: (0)若符号栈为空,无条件入栈当前指针指向的字符 (1)若w为不大于运算符栈栈顶的运算符,则从操作数栈NUM_S中弹出两个操作数,设先后弹出的操作数为a、b,再从运算符栈 OPR_S中弹出一个运算符,比如为+,然后作运算a+b,并将运算结果压入操作数栈NUM_S。 (2)若w为左括号或者运算符的优先级大于运算符栈栈顶的运算符,则将运算符W 压入运算符栈OPR_S,并继续扫描下一个字符。 (3)若运算符W为右括号,循环操作(设先后弹出的操作数为a、b,再从运算符栈OPR_S中弹出一个运算符,比如为+,然后作运 算a+b, 并将运算结果压入操作数栈NUM_S),直到从运算符栈中弹出第一个左括号。 (4)若运算符W为表达式结束符‘=’,循环操作(设先后弹出的操作数为a、b,再从运算符栈OPR_S中弹出一个运算符,比如为 +,然后作运算a+b, 并将运算结果压入操作数栈NUM_S),直到运算符栈为空为止。此时,操作数栈栈顶元素即为表达式的 值。 ====================================================================== === 举例:计算3+(5-2*3)/4-2= (1)开始栈为空,3入栈,+入栈,(无条件入栈,5入栈,-号优先级比(高,所以-号入栈,2入栈,*优先级比目前栈顶的-号优先级高,所以*入栈,3入栈,接着扫描到)括号,)括号不入栈 | | | | --------- ---------- | 3 | | * | --------- ---------- | 2 | | - |

数据结构课程设计报告

山东建筑大学 课程设计成果报告 题目: 1.数组实现两个矩阵的相乘运算 2.成绩分析问题 课程:数据结构A课程设计 院(部):管理工程学院 专业:信息管理与信息系统 班级:信管*** 学生姓名:*** 学号:******** 指导教师:******* 完成日期:2016年12月29日

目录 目录 (2) 一、课程设计概述 (3) 二、课程设计题目一 (3) 用数组实现两个矩阵的相乘运算 (3) 2.1[问题描述] (3) 2.2[要求及提示]: (3) 2.3[详细设计] (4) 2.4[调试分析] (5) 2.5[运行结果及分析] (5) 三、课程设计题目二 (6) 成绩分析问题 (6) 3.1[问题描述] (6) 3.2[概要设计] (6) 3.3[存储结构] (7) 3.4[流程图] (7) 3.5[详细设计] (8) 3.6[调试分析] (8) 3.7[运行结果及分析] (22) 四、参考文献: (25)

一、课程设计概述 本次数据结构课程设计共完成两个题:用数组实现两个矩阵相乘运算、成绩分析问题。使用语言:C 编译环境:vc6.0 二、课程设计题目一 用数组实现两个矩阵的相乘运算 2.1[问题描述] #include “stdio.h” int r[6][6]; void mult(int a[6][6] , int b[6][6]){ } main(){ int i,j; int num1[6][6],num2[6][6]; printf(“请输入第一个矩阵的值:”,); for(i=1;i<=6;i++) for(j=1;j<=6;j++) scanf(“%d”,&num1[i][j]); printf(“请输入第二个矩阵的值:”,); for(i=1;i<=6;i++) for(j=1;j<=6;j++) scanf(“%d”,&num2[i][j]); mult(num1,num2); printf(“\n两个矩阵相乘后的结果为:”); for(i=1;i<=6;i++) {for(j=1;j<=6;j++) printf(“%4d”,r[i][j]); printf(“\n”); } } 2.2[要求及提示]: 1、要求完善函数mult( ),

数据结构课程设计报告模板

课程设计说明书 课程名称:数据结构 专业:班级: 姓名:学号: 指导教师:成绩: 完成日期:年月日

任务书 题目:黑白棋系统 设计内容及要求: 1.课程设计任务内容 通过玩家与电脑双方的交替下棋,在一个8行8列的方格中,进行棋子的相互交替翻转。反复循环下棋,最后让双方的棋子填满整个方格。再根据循环遍历方格程序,判断玩家与电脑双方的棋子数。进行大小判断,最红给出胜负的一方。并根据y/n选项,判断是否要进行下一局的游戏。 2.课程设计要求 实现黑白两色棋子的对峙 开发环境:vc++6.0 实现目标: (1)熟悉的运用c语言程序编写代码。 (2)能够理清整个程序的运行过程并绘画流程图 (3)了解如何定义局部变量和整体变量; (4)学会上机调试程序,发现问题,并解决 (5)学习使用C++程序来了解游戏原理。 (6)学习用文档书写程序说明

摘要 本文的研究工作在于利用计算机模拟人脑进行下黑白棋,计算机下棋是人工智能领域中的一个研究热点,多年以来,随着计算机技术和人工智能技术的不断发展,计算机下棋的水平得到了长足的进步 该程序的最终胜负是由棋盘上岗双方的棋子的个数来判断的,多的一方为胜,少的一方为负。所以该程序主要运用的战术有削弱对手行动战术、四角优先战术、在游戏开局和中局时,程序采用削弱对手行动力战术,即尽量减少对手能够落子的位置;在游戏终局时则采用最大贪吃战术,即尽可能多的吃掉对手的棋子;而四角优先战术则是贯穿游戏的始终,棋盘的四角围稳定角,不会被对手吃掉,所以这里是兵家的必争之地,在阻止对手进角的同时,自己却又要努力的进角。 关键词:黑白棋;编程;设计

数据结构课程设计报告模板

校园导游系统设计 一、设计要求 1.问题描述 设计一个校园导游程序,为来访的客人提供信息查询服务。 2.需求分析 (1)设计学校的校园平面图。选取若干个有代表性的景点抽象成一个无向带权图(无向网),以图中顶点表示校内各景点,边上的权值表示两景点之间的距离。 (2)存放景点代号、名称、简介等信息供用户查询。 (3)为来访客人提供图中任意景点相关信息的查询。 (4)为来访客人提供图中任意景点之间的问路查询。 (5)可以为校园平面图增加或删除景点或边,修改边上的权值等。 二、概要设计 为了实现以上功能,可以从3个方面着手设计。 1.主界面设计 为了实现校园导游系统各功能的管理,首先设计一个含有多个菜单项的主控菜单子程序以链接系统的各项子功能,方便用户使用本系统。本系统主控菜单运行界面如图7-10所示。 2.存储结构设计 本系统采用图结构类型(mgraph)存储抽象校园图的信息。其中:各景点间的邻接关系用图的邻接矩阵类型(adjmatrix)存储;景点(顶点)信息用结构数组(vexs)存储,其中每个数组元素是一个结构变量,包含景点编号、景点名称及景点介绍三个分量;图的顶点个数及边的个数由分量vexnum、arcnum表示,它们是整型数据。 此外,本系统还设置了三个全局变量:visited[ ] 数组用于存储顶点是否被访问标志;d[ ]数组用于存放边上的权值或存储查找路径顶点的编号;campus是一个图结构的全局变量。 3.系统功能设计 本系统除了要完成图的初始化功能外还设置了8个子功能菜单。图的初始化由函数initgraph( )实现。依据读入的图的顶点个数和边的个数,分别初始化图结构中图的顶点向量数组和图的邻接矩阵。8个子功能的设计描述如下。 (1)学校景点介绍 学校景点介绍由函数browsecompus( )实现。当用户选择该功能,系统即能输出学校全部景点的信息:包括景点编号、景点名称及景点简介。 (2)查看浏览路线 查看浏览路线由函数shortestpath_dij( )实现。该功能采用迪杰斯特拉(Dijkstra)算法实现。当用户选择该功能,系统能根据用户输入的起始景点编号,求出从该景点到其它景点的最短路径线路及距离。 (3)查看两景点间最短路径

栈的应用表达式求值的设计

数据结构课程设计报告 栈的应用:表达式求值 专业 计算机科学与技术 学生姓名 班级 学 号 指导教师 完成日期 2014年7月4日

表达式求值的设计 目录 1设计内容 (1) 2设计分析 (1) 2.1后缀表达式设计 (1) 2.2 中缀到后缀的转换设计 (2) 3设计实践 (3) 3.1实现要求 (3) 3.2程序代码 (3) 4测试方法 (17) 4.1测试目的 (17) 4.2 测试输入 (17) 4.3 正确输出 (18) 4.4 实际输出 (18) 5程序运行效果 (18) 6设计心得 (19)

栈的应用:表达式求值的设计 1设计内容 设计一个表达式求值的程序。该程序必须可以接受包含(,),+,-,*,/,%,和^(求幂运算符,a^b=a b)的中缀表达式,并求出结果。如果表达式正确,则输出表达式的结果;如果表达式非法,则输出错误信息。 输入要求:程序从“input.txt”文件中读取信息,在这个文件中如果有多个中缀表达式,则每个表达式独占一行,程序的读取操作在文件在文件的结尾处停止。 输出要求:对于每个表达式,将其结果放在“output.txt”文件的每一行中。这些结果可能是值,也可能是错误信息“ERROR IN INFIX NOTATION”。 2 设计分析 在计算机中,算术表达式的计算往往是通过使用栈来实现的。所以,本表达式求值程序的最主要的数据结构就是栈。可以使用栈来存储输入表达式的操作符和操作数。 输入的表达式是由操作数(又称运算对象)和运算符以及改变运算次序的圆括号连接而成的式子。算术表达式有中缀表示法和后缀表示法,本程序输入的表达式采用中缀表示法,在这种表达式中,二元运算符位于两个操作数中间。 由于不同运算符之间存在优先级,同一优先级的运算间又存在着运算结合顺序的问题,所以简单的从左到右的计算是不充分的。当然凭直观判断一个中缀表达式中哪个运算符最先,哪个次之,哪个最后并不困难,但通过计算机处理就比较困难了。因为计算机只能一个字符一个字符地扫描,要想知道哪个运算符先算,就必须对整个中缀表达式扫描一遍。 而后缀表达式则很容易通过应用栈实现表达式的计算,这为实现表达式求值程序提供了一种直接的计算机制。 2.1后缀表达式设计 后缀表达式是由一系列的运算符、操作数组成的表达式,其中运算符位于两个操作数之后。后缀表达式很容易通过应用栈实现表达式的计算。其基本过程是:当输入一个操作数时,它被压入栈中,当一个运算符出现时,就从栈中弹出适当数量的操作数,对该运算进行计算,计算结果再压回栈中。对于最常见的二元运算符来说,弹出的操作数只有两个。处理完整个后缀表达式之后,栈顶上的元素就是表达式的结果值。整个计算过程不需要理解计算的优先级规则。

数据结构课程设计报告范例

Guangxi University of Science and Technology 课程设计报告 课程名称:算法与编程综合实习 课题名称: 姓名: 学号: 院系:计算机学院 专业班级:通信121 指导教师: 完成日期:2012年12月15日

目录 第1部分课程设计报告 (3) 第1章课程设计目的 (3) 第2章课程设计内容和要求 (4) 2.1 问题描述 (4) 2.2 设计要求 (4) 第3章课程设计总体方案及分析 (4) 3.1 问题分析 (4) 3.2 概要设计 (7) 3.3 详细设计 (7) 3.4 调试分析 (10) 3.5 测试结果 (10) 3.6 参考文献 (12) 第2部分课程设计总结 (13) 附录(源代码) (14)

第1部分课程设计报告 第1章课程设计目的 仅仅认识到队列是一种特殊的线性表是远远不够的,本次实习的目的在于使学生深入了解队列的特征,以便在实际问题背景下灵活运用它,同时还将巩固这种数据结构的构造方………………………………………………………………………………………………………………………………………………………………………………………..(省略)

第2章课程设计内容和要求 2.1问题描述: 迷宫问题是取自心理学的一个古典实验。在该实验中,把一只老鼠从一个无顶大盒子的门放入,在盒子中设置了许多墙,对行进方向形成了多处阻挡。盒子仅有一个出口,在出口处放置一块奶酪,吸引老鼠在迷宫中寻找道路以到达出口。对同一只老鼠重复进行上述实验,一直到老鼠从入口走到出口,而不走错一步。老鼠经过多次试验最终学会走通迷宫的路线。设计一个计算机程序对任意设定的矩形迷宫如下图A所示,求出一条从入口到出口的通路,或得出没有通路的结论。 图A 2.2设计要求: 要求设计程序输出如下: (1) 建立一个大小为m×n的任意迷宫(迷宫数据可由用户输入或由程序自动生成),并在屏 幕上显示出来; (2)找出一条通路的二元组(i,j)数据序列,(i,j)表示通路上某一点的坐标。 (3)用一种标志(如数字8)在迷宫中标出该条通路; (4)在屏幕上输出迷宫和通路; (5)上述功能可用菜单选择。

数据结构课程设计报告

《数据结构课程设计》报告 题目:课程设计题目2教学计划编制 班级:700 学号:09070026 姓名:尹煜 完成日期:2011年11月7日

一.需求分析 本课设的任务是根据课程之间的先后的顺序,利用拓扑排序算法,设计出教学计划,在七个学期中合理安排所需修的所有课程。 (一)输入形式:文件 文件中存储课程信息,包括课程名称、课程属性、课程学分以及课程之间先修关系。 格式:第一行给出课程数量。大于等于0的整形,无上限。 之后每行按如下格式“高等数学公共基础必修6.0”将每门课程的具体信息存入文件。 课程基本信息存储完毕后,接着给出各门课程之间的关系,把每门课程看成顶点,则关系即为边。 先给出边的数量。大于等于0的整形。 默认课程编号从0开始依次增加。之后每行按如下格式“1 3”存储。此例即为编号为1的课程与编号为3的课程之间有一条边,而1为3的前驱,即修完1课程才能修3课程。 例: (二)输出形式:1.以图形方式显示有向无环图

2.以文本文件形式存储课程安排 (三)课设的功能 1.根据文本文件中存储的课程信息(课程名称、课程属性、课程学分、课程之间关系) 以图形方式输出课程的有向无环图。 拓展:其显示的有向无环图可进行拖拽、拉伸、修改课程名称等操作。 2.对课程进行拓扑排序。 3.根据拓扑排序结果以及课程的学分安排七个学期的课程。 4.安排好的教学计划可以按图形方式显示也可存储在文本文件里供用户查看。 5.点击信息菜单项可显示本人的学好及姓名“09070026 尹煜” (四)测试数据(见六测设结果)

二.概要设计 数据类型的定义: 1.Class Graph即图类采用邻接矩阵的存储结构。类中定义两个二维数组int[][] matrix 和Object[][] adjMat。第一个用来标记两个顶点之间是否有边,为画图服务。第二个 是为了实现核心算法拓扑排序。 2.ArrayList list用来存储课程信息。DrawInfo类是一个辅助画图的类,其中 包括成员变量num、name、shuxing、xuefen分别代表课程的编号、名称、属性、 学分。ArrayList是一个DrawInfo类型的数组,主要用来在ReadFile、DrawG、DrawC、SaveFile、Window这些类之间辅助参数传递,传递课程信息。 3.Class DrawInfo, 包括int num;String name;String shuxing;float xuefen;四个成员变量。 4.Class Edge包括int from;int to;double weight;三个成员变量。 5.Class Vertex包括int value一个成员变量。 主要程序的流程图: //ReadFile.java

实验2 栈和队列的应用-算术表达式求值

1.实验题目 栈和队列的应用 2.实验内容 算术表达式求值 3.实验目的 掌握栈和队列的概念及工作原理,运用其原理完成实验题目中的内容。 4.实验要求 为了更好的掌握与理解课堂上老师所讲的概念与原理,实验前要认真预习所做的实验内容及编写源程序伪码(写在纸上及盘中均可)以便在实验课中完成老师所布置的实验内容。 5.概要设计原理 6.详细程序清单及注释说明 #include #include #include #include #define NULL 0 #define OK 1 #define OVERFLOW -2 #define STACK_INIT_SIZE 100 #define STACKINCREMENT 20 /* 定义字符类型栈*/ typedef struct { int stacksize; char *base; char *top; }SqStack; /* ----------------- 全局变量--------------- */ SqStack OPTR,OPND;// 定义运算符栈和操作数栈 char expr[255]; /* 存放表达式串*/ char *ptr=expr; int InitStack(SqStack *s) //构造运算符栈 { s->base=(char *)malloc(STACK_INIT_SIZE*sizeof(char)); if(!s->base) exit(OVERFLOW);

s->top=s->base; s->stacksize=STACK_INIT_SIZE; return OK; } char In(char ch) //判断字符是否是运算符,运算符即返回1 { return(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')'||ch=='#'); } int Push(SqStack *s,char ch) //运算符栈插入ch为新的栈顶元素{ *s->top=ch; s->top++; return 0; } char Pop(SqStack *s) //删除运算符栈s的栈顶元素,用p返回其值{ char p; s->top--; p=*s->top; return p; } char GetTop(SqStack s)//用p返回运算符栈s的栈顶元素 { char p=*(s.top-1); return p; } /* 判断运算符优先权,返回优先权高的*/ char Precede(char c1,char c2) { int i=0,j=0; static char array[49]={ '>', '>', '<', '<', '<', '>', '>', '>', '>', '<', '<', '<', '>', '>', '>', '>', '>', '>', '<', '>', '>', '>', '>', '>', '>', '<', '>', '>', '<', '<', '<', '<', '<', '=', '!', '>', '>', '>', '>', '!', '>', '>', '<', '<', '<', '<', '<', '!', '='};

利用栈求表达式的值,可供小学生作业,并能给出分数 数据结构课程设计说明书格式

中北大学 数据结构 课程设计说明书 2011年12月20日

1. 设计任务概述(包括系统总体框图及功能描述) 此课题是研究表达式求值的问题,以帮助小学生完成测试。为了达到这个功能,实际我们要做的就是出题,和计算分数给出评价的工作。整体设计都是以这个要求为轴心进行的。为了直观和方便,现画出软件整体设计模块图。 整体设计模块图可以清晰的看出软件的几大模块。整个系统的操作流程图可以看出操作的整体流程,如下图 2.

根据以上功能说明,设计运算信息,堆栈的存储结构,设计程序完成功能; 3. 功能模块详细设计 在此说明每个部分的算法设计说明(可以是描述算法的流程图),每个程序中使用的存储结构设计说明(如果指定存储结构请写出该存储结构的定义)。 3.1 详细设计思想 学生要进行测试,首先要有试题。那么我们就要先建立试题库。这个试题库的试题是我们在程序运行过程中手动输入,存放在一个shujuku.txt的文件中。 首先在主函数中调用创建试题库函数,将试题存入到试题库文件shitiku.txt中,然后将该调用从主函数中删除。 创建试题库函数:创建指向xuanti类型的指针,利用循环将输入的测试题该指针的xuanti单元中,最后将该指针中的测试题写入试题库文件shitiku.txt中。 3.2 核心代码 (正文宋体小四号字,1.5倍行距) #include #include #include #include #include #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10 #define ERROR 0 #define OK 1 //定义表达式

最新数据结构课程设计题目

数据结构课程设计 一、考核方法和内容 根据课程设计过程中学生的学生态度、题目完成情况、课程设计报告书的质量和回答问题的情况等按照10%、40%、30%、20%加权综合打分。成绩评定实行优秀、良好、中等、及格和不及格五个等级。评分标准: 优秀:答辩所有问题都能答出+报告良好 或报告良好+实现“提高部分”的功能; 良好:答辩所有问题都能答出+报告一般; 或报告一般+实现“提高部分”的功能; 中等:答辩大部分问题能答出+报告良好; 及格:答辩大部分问题能答出+报告一般; 以下四种,都不及格: 1)答辩几乎答不出问题; 2)报告几乎都是代码; 3)雷同部分达到60%; 4)课设报告与数据结构和c/c++关联不大。 课设报告的装订顺序如下: 任务书(签名,把题目要求贴在相应位置,注意下划线)-----目录(注意目录的格式,页码)-----1、设计任务(题目要求)-----2、需求分析(准备选用什么数据逻辑结构?数据元素包含哪些属性?需要哪些函数?为什么要这样设计?最后列出抽象数据类型定义)-----3、系统设计(设计实现抽象数据类型,包含选择什么物理存储方式?数据元素的结构体或类定义,以及各函数的设计思路,算法,程序流程图等)----4、编码实现(重要函数的实现代码)-----5、调试分析(选择多组测试数据、运行截图、结果分析)-----6、课设总结(心得体会)-----7、谢辞-----8、参考文献; 课设报告打印要求: B5纸张打印,报告总页数控制在10—15页内,报告中不能全是代码,报告中代码总量控制在3页内。版式:无页眉,有页码,页码居中 字号:小四,单倍行距 字体:宋体+Times new Romar 截图:截图要配图的编号和图的题目,如:“图1 Insert函数流程图” 二、课程设计的题目 1.长整数的加法运算 2.通讯录管理系统的设计与实现——顺序表 3.广义表的应用 4.学生成绩管理系统的设计与实现 5.家谱管理系统的设计与实现 6.集合的并、交和差运算的程序 7.运动会分数统计 8.一元多项式计算器 9.文章编辑 10.哈夫曼树及其编码 11.校园导游咨询 12.通讯录管理系统的设计与实现——单链表 13.地图着色问题 14.内部排序算法比较 15.火车售票系统 16.图书管理系统 17.客户消费积分管理系统 18.产品进销存管理系统

数据结构课程设计

《数据结构》 课程设计报告 学号 姓名 班级 指导教师 安徽工业大学计算机学院 2010年6月

建立二叉树和线索二叉树 1.问题描述: 分别用以下方法建立二叉树并用图形显示出来: 1)用先序遍历的输入序列 2)用层次遍历的输入序列 3)用先序和中序遍历的结果 2.设计思路: 分三个方式去实现这个程序的功能,第一个实现先序遍历的输入数列建立二叉树;第二个是用层次遍历的方法输入序列;第三个是用先序和后序遍历的结果来建立二叉树;三种方法建立二叉树后都进行输出。关键是将这三个实现功能的函数写出来就行了;最后对所建立的二叉树进行中序线索化,并对此线索树进行中序遍历(不使用栈)。 3.数据结构设计: 该程序的主要目的就是建立二叉树和线索二叉树,所以采用树的存储方式更能完成这个程序; 结点的结构如下: typedef struct bnode { DataType data; int ltag,rtag; struct bnode *lchild, *rchild; } Bnode, *BTree; 4.功能函数设计: BTree CreateBinTree() 用先序遍历的方法讲二叉树建立; BTree CREATREE() 用队列实现层次二叉树的创建; void CreatBT(); 用先序和中序遍历的结果建立二叉树; void InThread(BTree t,BTree pre) 中序线索化; 5.编码实现: #include #include #define max 100 typedef struct bnode { char data; int ltag,rtag; struct bnode *lchild,*rchild; }Bnode,*BTree; BTree Q[max]; BTree CREATREE() { char ch; int front=1,rear=0;

数据结构课程设计

一、高校社团管理 在高校中,为了丰富学生的业余生活,在学校的帮助下,会成立许多社团,少则几个,多则几十个。为了有效管理这些社团,要求编写程序实现以下功能:1.社团招收新成员; 2.修改社团相应信息 3.老成员离开社团 4.查询社团情况; 5.统计社团成员数; 二、简单文本编辑器 设计一个文本编辑器,允许将文件读到内存中,也就是存储在一个缓冲区中。这个缓冲区将作为一个类的内嵌对象实现。缓冲区中的每行文本是一个字符串,将每行存储在一个双向链表的结点中,要求设计在缓冲区中的行上执行操作和在单个行中的字符上执行字符串操作的编辑命令。 基本要求: 包含如下命令列。可用大写或小写字母输入。 R:读取文本文件到缓冲区中,缓冲区中以前的任何内容将丢失,当前行是文件的第一行; W:将缓冲区的内容写入文本文件,当前行或缓冲区均不改变。 I:插入单个新行,用户必须在恰当的提示符的响应中键入新行并提供其行号。 D:删除当前行并移到下一行; F:可以从第1行开始或从当前行开始,查找包含有用户请求的目标串的第一行; C:将用户请求的字符串修改成用户请求的替换文本,可选择是仅在当前行中有效的还是对全文有效的。 Q:退出编辑器,立即结束; H:显示解释所有命令的帮助消息,程序也接受?作为H的替代者。 N:当前行移到下一行,也就是移到缓冲区的下一行; P:当前行移到上一行,也就是移到缓冲区的上一行;

B:当前行移到开始处,也就是移到缓冲区的第一行; E:当前行移到结束处,也就是移到缓冲区的最后一行; G:当前行移到缓冲区中用户指定的行; V:查看缓冲区的全部内容,打印到终端上。 三、电话客户服务模拟 一个模拟时钟提供接听电话服务的时间(以分钟计),然后这个时钟将循环的 自增1(分钟)直到达到指定时间为止。在时钟的每个"时刻",就会执行一次检查来看看对当前电话服务是否已经完成了,如果是,这个电话从电话队列中删除,模 拟服务将从队列中取出下一个电话(如果有的话)继续开始。同时还需要执行一个检查来判断是否有一个新的电话到达。如果是,其到达时间被记录下来,并为其产生一个随机服务时间,这个服务时间也被记录下来,然后这个电话被放入电话队列中,当客户人员空闲时,按照先来先服务的方式处理这个队列。当时钟到达指定时间时,不会再接听新电话,但是服务将继续,直到队列中所偶电话都得到处理为止。 基本要求: (1)程序需要的初始数据包括:客户服务人员的人数,时间限制,电话的到达速率,平均服务时间 (2)程序产生的结果包括:处理的电话数,每个电话的平均等待时间 四、停车场管理 设停车场是一个可停放n辆车的狭长通道,且只有一个大门可供汽车进出。在停车场内,汽车按到达的先后次序,由北向南依次排列(假设大门在最南端)。若停车场内已停满n辆车,则后来的汽车需在门外的便道上等候,当有车开走时,便道上的第一辆车即可开入。当停车场内某辆车要离开时,在它之后进入的车辆必须先退出停车场为它让路,待该辆车开出大门后,其他车辆再按原次序返回车场。每辆车离开停车场时,应按其停留时间的交费(从进入便道开始计时)。在这里假设汽车从便道上开走时不收取任何费用 基本要求: (1)汽车的输入信息格式为(到达/离去的标识,汽车牌照号码,到达/离去的时间)

基于栈结构的中缀表达式求值

实验3:栈与队列实验 ——基于栈结构的中缀表达式求值 一、问题描述 从键盘输入任意中缀表达式字符串,读字符串,利用栈结构实现表达式求值。 二、输入与输出 输入:从键盘中缀表达式如: 32+5×(6-4) 输出:计算结果42 三、需求分析 1.定义两个栈结构,数栈用于存放表达式中的数,符号栈用于存放表达式中的符号,实现栈的运算 2.在读数的时候考虑多位运算 3.实现表达式求值 四、开发工具与环境 硬件设备:微型计算机系统 软件环境:操作系统Windows 开发工具:Devc++ 五、概要设计 参考结构定义 typedef struct /* 运算符栈 */ { char *base,*top; int stacksize; }SqStack; typedef struct /* 运算数栈 */ { int *base,*top; int stacksize; }SqStack1; int priority[7][7]={{'>', '>', '<', '<', '<', '>', '>'}, // + {'>', '>', '<', '<', '<', '>', '>'}, // -

{'>', '>', '>', '>', '<', '>', '>'}, // * {'>', '>', '>', '>', '<', '>', '>'}, // / {'<', '<', '<', '<', '<', '=', ' '}, // ( {'>', '>', '>', '>', ' ', '>', '>'}, // ) {'<', '<', '<', '<', '<', ' ', '='} // # }; /*用于比较符号优先级的全局二维数组*/ 2.各函数模块 void InitStack(SqStack *s); 操作结果:初始化运算符栈 char GetTop(SqStack *s); 操作结果:得到运算符栈的栈顶元素 void Push(SqStack *s,char e); 操作结果:对运算符栈进行压栈操作 int IsNumber(char c); 操作结果:判断一个字符是否是数字 int MidExpression_Eval(char Express[]); 操作结果:计算中缀表达式的值 int Operate (int a,char x,int b); 操作结果:计算表达式axb,并返回结果 六、详细设计 #include #include using namespace std; /*定义区*/ #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10 #define OVERFLOW -1 #define ERROR 0 #define OK 1 //运算符栈 typedef struct { char *base, *top; int stacksize; }SqStack; //运算数栈 typedef struct { int *base, *top; int stacksize;

带括号的四则运算表达式的求值栈实现

带括号的四则运算表达式的求值(栈实现) 利用栈这种数据结构来实现一个加减乘除以及带括弧的混合数学表达式的计算,对于数学表达式的计算,可以设置一个运算符栈和一个数字栈,分别来保存运算符、数字或者中间计算得到的结果。将整个表达式看做一个字符串,从开头依次判断每个字符是运算符还是数字,若是运算符,则根据运算符优先级来确定是将其压栈还是弹栈进行计算;若是数字,则先将其转化并计入一个临时double型变量中,看下一个字符是否为运算符栈,若是,则将临时变量压进数字栈,否则读取下一个数字字符并进行相关处理后累加到临时变量中,直到下一个字符为运算符,将临时变量压进数字栈。最后,当字符为"="时,结束计算,得到计算结果。本算法需要先设置一个运算符优先级表,下表可供参考: +-*/()= +>><<<>> ->><<<>> *>>>><>> />>>><>> (<<<<<= )>>>>?>> =<<<<

while(!IsOper(s[j])) { { point = 10; j++; continue; } if(!point)? 5 - 7 / 2 + 3. - .1 1 + 2 / ( 2 - / ) - 3 2 * ( ( 3 + 2 ) - 3 */ 本代码生成的程序,在输入表达式时,数字与运算符之间可以有若干空格或者没有;对于小数,可以没有整数部分(即小数点之前没有数字),也可以没有小数部分(即小数点之后没有数字);表达式可以为无效表达式(如括号不匹配或者出现除数为0的情况等);如以上的样例输入。对于以上样例输入,其对应输出结果为: The divisor cannot be zero! The parentheses do not match!

数据结构课程设计全集

数据结构实践教程

前言 数据结构是计算机专业的必修。主干课程之一,它旨在使读者学会分析研究数据对象的特性,学会数据的组织方法, 以便选择合适的数据逻辑结构和存储结构, 以及相应的运算(操作),把现实世界中的问题转化为计算机内部的表示和处理,这是一个良好的程序设计技能训练的过程. 在整个教学或学习过程中,解题能力和技巧的训练是一个重要的环节。为了帮助教师讲授“数据结构",满足指导和评价“课程设计”的需要, 为了帮助和指导读者更好地学习数据结构这门课程,我们特编写了这本《数据结构实践教程》辅助教材,旨在弥补课堂教学和实验中的不足,帮助学生充分理解和巩固所学的基本概念、原理和方法,达到融会贯通、举一反三的目的。 实践证明,理解课程内容与较好地解决实际问题之间存在着明显差距,而算法设计完成的质量与基本的程序设计素质的培养是密切相关的。要想理解和巩固所学的基本概念。原理和方法, 牢固地掌握所学的基本知识。基本技能, 达到融会贯通。举一反三的目的, 就必须多做。多练。多见(见多识广)。正是为了达到上述目的,书中用一些实际的应用,对一些重要的数据结构和算法进行解读。经过循序渐进地训练, 就可以使读者掌握更多的程序设计技巧和方法,提高分析。解决问题的能力。 本书根据学生的基础知识和兴趣爱好将内容分为基础篇和提高篇两个部分。第一部分基础篇精选出适当的、与实际生活结合密切的课程设计实例加以分析实现。第二部分提高篇旨在使读者通过运用数据结构知识及复杂算法去解决现实世界中的一些实际问题。 本书依据数据结构课程教学大纲要求,同时又独立于具体的教科书,既重视实践应用,又重视理论分析,本书的主要特点有: ●本书精选出来的实例项目经典、实用、具有一定的趣味性,其内容丰富、涉及面广、难易适当,能给读者以启发,达到让读者掌握相关知识和开阔视野的目的 ●为了提高学生分析问题、解决问题的能力,本书对实例项目进行分析,其设计思路清晰流畅,值得参考. ●本书不仅仅是对照数据结构课程教学大纲举些例子说明数据结构能解决什么问题,而是通过分析具体的实例项目,得到对数据组织关系的需求,从而选择某个数据结构适应一些特定的问题和算法,并说明使用这种数据结构的优缺点. ●所有实例项目都给出了参考算法和源程序代码并在Turbo C和VisualC++6.0环境下运行通过。 由于作者水平有限、时间仓促,本书难免存在一些缺点和错误,恳请广大读者及同行们批评指正。

数据结构课程设计报告

数据结构课程设计报告 题目:5 班级:计算机1102 学号:4111110030 姓名:陈越 指导老师:王新胜

一:需求分析 1.运行环境 TC 2.程序所需实现的功能 几种排序算法的演示,要求给出从初始开始时的每一趟的变化情况,并对各种排序算法性能作分析和比较: (1)直接插入排序; (2)折半插入排序; (3)冒泡排序; (4)简单选择排序; (5)快速排序; (6)堆排序; (7)归并排序. 二:设计说明 1.算法设计的思想 1)、直接插入排序 排序过程:整个排序过程为n-1趟插入,即先将序列中第1个记录看成是一个有序子序列,然后从第2个记录开始,逐个进行插入,直至整个序列有序。 2)、折半插入排序 排序过程:用折半查找方法确定插入位置的排序叫折半插入排序。 3)、冒泡排序

排序过程:将第一个记录的关键字与第二个记录的关键字进行比较,若为逆序r[1].key>r[2].key,则交换;然后比较第二个记录与第三个记录;依次类推,直至第n-1个记录和第n个记录比较为止——第一趟冒泡排序,结果关键字最大的记录被安置在最后一个记录上。对前n-1个记录进行第二趟冒泡排序,结果使关键字次大的记录被安置在第n-1个记录位置。重复上述过程,直到“在一趟排序过程中没有进行过交换记录的操作”为止 4)、简单选择排序 排序过程:首先通过n-1次关键字比较,从n个记录中找出关键字最小的记录,将它与第一个记录交换。再通过n-2次比较,从剩余的n-1个记录中找出关键字次小的记录,将它与第二个记录交换。重复上述操作,共进行n-1趟排序后,排序结束。 5)、快速排序 基本思想:通过一趟排序,将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录进行排序,以达到整个序列有序。 排序过程:对r[s……t]中记录进行一趟快速排序,附设两个指针i和j,设枢轴记录rp=r[s],x=rp.key。初始时令i=s,j=t。首先从j所指位置向前搜索第一个关键字小于x的记录,并和rp交换。再从i所指位置起向后搜索,找到第一个关键字大于x的记录,和rp交换。重复上述两步,直至i==j为止。再分别对两个子序列进行快速排序,直到每个子序列只含有一个记录为止。 6)、堆排序 排序过程:将无序序列建成一个堆,得到关键字最小(或最大)的记录;输

相关主题