算法与数据结构.docx

上传人:b****6 文档编号:5164958 上传时间:2022-12-13 格式:DOCX 页数:37 大小:245.12KB
下载 相关 举报
算法与数据结构.docx_第1页
第1页 / 共37页
算法与数据结构.docx_第2页
第2页 / 共37页
算法与数据结构.docx_第3页
第3页 / 共37页
算法与数据结构.docx_第4页
第4页 / 共37页
算法与数据结构.docx_第5页
第5页 / 共37页
点击查看更多>>
下载资源
资源描述

算法与数据结构.docx

《算法与数据结构.docx》由会员分享,可在线阅读,更多相关《算法与数据结构.docx(37页珍藏版)》请在冰豆网上搜索。

算法与数据结构.docx

算法与数据结构

 

数据结构与算法课程设计

 

题目:

集合的计算表达式转换问题

八皇后问题

构造使n个城市连接的最小生成树

目录

摘要4

一.集合的计算4

1.采用类语言定义相关的数据类型4

2.算法设计4

3.函数的调用关系图5

4.调试分析6

5.测试结果6

6.源程序(带注释)6

二.表达式转换问题7

1.采用类语言定义相关的数据类型12

2.算法设计13

3.函数的调用关系图14

4.调试分析14

5.测试结果14

6.源程序(带注释)15

三.八皇后问题16

1.采用类语言定义相关的数据类型16

2.算法设计16

3.函数的调用关系图18

4.调试分析19

5.测试结果20

6.源程序(带注释)20

四.构造可以使n个城市连接的最小生成树16

1.采用类语言定义相关的数据类型16

2.算法设计16

3.函数的调用关系图18

4.调试分析19

5.测试结果20

6.源程序(带注释)20

总结35

参考文献36

致谢36

摘要

1.通过程序实现两个集合的交并差运算和一个集合的冥集运算

2.输入一个中缀表达式,通过程序输出一个后缀表达式

3.通过程序将八个皇后放置在国际象棋棋盘的无冲突的位置上的算法,并给出所有的解

4.给定一个地区的n个城市间的距离网,用Prim算法或Kruskal算法建立最小生成树,并计算得到的最小生成树的代价

关键词:

线性表;链栈;列队;树

一.集合的计算

设计一个程序,实现两个集合的并集、交集、差集、显示输出等,要求结果集合中的元素不重复;实现一个集合的幂集的求解。

1.采用类语言定义相关的数据类型

typedefintElemType;

typedefstruct{//线性表的结构体

ElemTypedata[MAXSIZE];

intlength;

}SqList;

2.算法设计

A.初始化三个线性表,第一个和第二个线性表分别为两个集合,第三个线性表为计算后的集合

voidInitList(SqList*L){//初始化线性表

L->data==NULL;

L->length=0;

}

B.求并集,把集合1和集合2中的元素不重复的放入集合2中

voidoperate4(SqList*L1,SqList*L2,SqList*L3){//求并集

inti,j;

ElemTyperes_date;

InitList(L3);//初始化L3

for(i=0;ilength;i++){//将属于L1同时也属于L2的元素赋值给L3

res_date=L1->data[i];

for(j=0;jlength;j++){

if(res_date==L2->data[j]){

L3->data[L3->length]=res_date;

L3->length++;

break;

}

}

}

C.求交集,把即存在于集合1又存在于集合2的元素放入集合3中

D.求差集,把存在于集1合1但不存在于集合2的元素放入集合3中

E.求该集合的任意个元素的组合,所有的组合加上空集即是该集合的冥集

3.函数的调用关系图

 

 

4.调试分析

a、输入的数据类型不统一。

解决办法:

对输入的数据进行筛选和检验

b、算法的时间复杂度为o(n2)

c、算法的空间复杂度为o(n2)

5.测试结果

例:

集合1为{1,3,6,9,11}

集合2为{2,4,5,9,12}

求并集结果:

求差集结果:

6.源程序(带注释)

/*实现两个集合的并集、交集、差集,实现一个集合的幂集的求解。

程序中的线性表L1、L2分别为集合L1、L2,线性表L3为计算后的集合*/

#include

#defineMAXSIZE10//线性表的最大长度

typedefintElemType;

typedefstruct{//线性表的结构体

ElemTypedata[MAXSIZE];

intlength;

}SqList;

////////////////线性表的操作函数//////////////////////////////

voidInitList(SqList*L){//初始化线性表

L->data==NULL;

L->length=0;

}

intListInsert(SqList*L,inti,ElemTypee){//向表中插入元素

intk;

if(i<=L->length){//如果不在表尾插入

for(k=L->length-1;k>=i-1;k--){

L->data[k+1]=L->data[k];

}

L->data[i-1]=e;

L->length++;

return1;

}

else{//如果在表尾插入

L->data[i-1]=e;

L->length++;

return1;

}

}

voidErgList(SqList*L){//遍历线性表并依次返回元素

intj;

ElemTyperes_date;

for(j=0;jlength;j++){

res_date=L->data[j];

printf("%4d",res_date);

}

printf("\n");

}

////////////////该程序的操作函数/////////////////////////////////

intmenu(){//菜单函数

intm_cho;

system("cls");

printf("--------MENU--------\n");

printf("1->给集合L1和集合L2添加元素\n");

printf("2->查看集合L1,L2\n");

printf("3->求L1与L2的并集\n");

printf("4->求L1与L2的交集\n");

printf("5->求L1与L2的差集\n");

printf("6->求L1的冥集\n");

printf("7->求L2的冥集\n");

printf("8->退出系统\n");

printf("--------------------\n");

printf("--请输入序号:

[]\b\b");

scanf("%d",&m_cho);

if(1<=m_cho&&m_cho<=6)

returnm_cho;

else{

system("cls");

exit();

return0;

}

}

voidoperate1(SqList*L1,SqList*L2){//处理序号1

inti;

ElemTypeins_e[5];

printf("请输入集合L1中的元素(仅限整数):

\n");

for(i=0;i<5;i++){//接受集合L1的元素

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

ListInsert(L1,i+1,ins_e[i]);

}

printf("请输入集合L2中的元素(仅限整数):

\n");

for(i=0;i<5;i++){//接受集合L2的元素

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

ListInsert(L2,i+1,ins_e[i]);

}

}

voidoperate2(SqList*L1,SqList*L2){//处理序号2

printf("-------查看元素-------\n");

printf("集合L1:

");

ErgList(L1);

printf("集合L2:

");

ErgList(L2);

printf("----------------------\n");

}

voidoperate3(SqList*L1,SqList*L2,SqList*L3){//处理序号3

inti,j;

InitList(L3);//初始化L3

*L3=*L1;

for(i=0;ilength;i++){//将L2中的元素放入L3中且无重复元素

for(j=0;jlength;j++){

if(L3->data[j]==L2->data[i])//选择存在于L2但不存在于L3的元素

break;

else{

if(j==L3->length-1)

ListInsert(L3,L3->length+1,L2->data[i]);

else

continue;

}

}

}

printf("-------求并集结果-------\n");

ErgList(L3);

printf("-----------------------\n");

}

voidoperate4(SqList*L1,SqList*L2,SqList*L3){//处理序号4

inti,j;

ElemTyperes_date;

InitList(L3);//初始化L3

for(i=0;ilength;i++){//将属于L1同时也属于L2的元素赋值给L3

res_date=L1->data[i];

for(j=0;jlength;j++){

if(res_date==L2->data[j]){

L3->data[L3->length]=res_date;

L3->length++;

break;

}

}

}

printf("-------求交集结果-------\n");

ErgList(L3);

printf("-----------------------\n");

}

voidoperate5(SqList*L1,SqList*L2,SqList*L3){//处理序号5

inti,j;

ElemTyperes_date;

InitList(L3);//初始化L3

for(i=0;ilength;i++){//将属于L1但不属于L2的元素赋值给L3

res_date=L1->data[i];

for(j=0;jlength;j++){

if(res_date==L2->data[j]){

break;

}

else{

if(j==L2->length-1){

L3->data[L3->length]=res_date;

L3->length++;

}

else

continue;

}

}

}

printf("-------求差集结果-------\n");

ErgList(L3);

printf("-----------------------\n");

}

voidoperate6(SqList*L1,SqList*L3){//处理序号6

}

voidoperate7(SqList*L2,SqList*L3){//处理序号7

}

intmain(){

intc;

charres;

SqListL1,L2,L3;//定义线性表L1,L2,L3

InitList(&L1);//初始化线性表

InitList(&L2);

InitList(&L3);

start:

c=menu();

switch(c){//处理所选的操作

case1:

{

operate1(&L1,&L2);

printf(">>>元素输入成功!

0_0\n");

printf(">>>按ENTER键返回...");

scanf("%c",&res);

scanf("%c",&res);

gotostart;

}

case2:

{

operate2(&L1,&L2);

printf(">>>元素查看成功!

0_0\n");

printf(">>>按ENTER键返回...");

scanf("%c",&res);

scanf("%c",&res);

gotostart;

}

case3:

{

operate3(&L1,&L2,&L3);

printf(">>>L1与L2求并集成功!

0_0\n");

printf(">>>按ENTER键返回...");

scanf("%c",&res);

scanf("%c",&res);

gotostart;

}

case4:

{

operate4(&L1,&L2,&L3);

printf(">>>L1与L2求交集成功!

0_0\n");

printf(">>>按ENTER键返回...");

scanf("%c",&res);

scanf("%c",&res);

gotostart;

}

case5:

{

operate5(&L1,&L2,&L3);

printf(">>>L1与L2求差集成功!

0_0\n");

printf(">>>按ENTER键返回...");

scanf("%c",&res);

scanf("%c",&res);

gotostart;

}

case6:

{

operate6(&L1,&L3);

printf(">>>求L1的冥集成功!

0_0\n");

printf(">>>按ENTER键返回...");

scanf("%c",&res);

scanf("%c",&res);

gotostart;

}

case7:

{

operate7(&L2,&L3);

printf(">>>求L2的冥集成功!

0_0\n");

printf(">>>按ENTER键返回...");

scanf("%c",&res);

scanf("%c",&res);

gotostart;

}

}

return0;

}

二.表达式转换问题

请编写一个读取中缀表达式并生成后缀表达式的程序。

1.采用类语言定义相关的数据类型

typedefstructStackNode{//结点结构体

chardata;

structStackNode*next;

}StackNode,*LinkStackPtr;

typedefstructLinkStack{//链栈结构体

LinkStackPtrtop;

intcount;

}LinkStack;

2.算法设计

先通过栈将所输入的数据进行存储

逐个判断运算符的优先级

intPriority(DataTypeop){

switch(op){

case'(':

case'#':

return(0);

case'-':

case'+':

return

(1);

case'*':

case'/':

return

(2);

}

}

然后再通过栈将数字与运算符输出

函数的调用关系图

4.调试分析

2.调试中遇到的问题及对问题的解决方法

3.问题:

得到的后缀表达式不正确

4.解决办法:

使用栈把优先级低的运算符先保存下来

5.时间复杂度:

O(n)

6.空间复杂度:

O(n)

5.测试结果

6.源程序(带注释)

/求运算符优先级函数

intPriority(DataTypeop){

switch(op){

case'(':

case'#':

return(0);

case'-':

case'+':

return

(1);

case'*':

case'/':

return

(2);

}

}

/*转换函数将中缀表达式转换成后缀表达式*/

voidChangeExp(SeqQueue*Q){

SeqStackOS;//运算符栈

charc,t;

SeqStack*S;

S=&OS;

InitStack(S);//初始化栈

Push(S,'#');//压入栈底元素#

do{//扫描中缀表达式

c=getchar();

switch(c){

case'':

break;//去除空格符

case'1':

case'2':

case'3':

case'4':

case'5':

case'6':

case'7':

case'8':

case'9':

EnQueue(Q,c);break;

case'(':

Push(S,c);break;

case')':

case'#':

do{

t=Pop(S);

if(t!

='('&&t!

='#')

EnQueue(Q,t);

}while(t!

='('&&S->top!

=-1);break;

case'+':

case'-':

case'*':

case'/':

while(Priority(c)<=Priority(GetTop(S))){

t=Pop(S);

EnQueue(Q,t);

}

Push(S,c);break;

}//EndSwitch

}while(c!

='#');//以#号结束表达式扫描

}

三.八皇后问题

要求编写程序实现将八个皇后放置在国际象棋棋盘的无冲突的位置上的算法,并给出所有的解。

提示:

在国际象棋上放置皇后时,任何一个皇后的水平、竖直和斜45º都不能有另一个皇后。

解决该问题采用逐次试探的方法,即采用递归调用putchess函数的方法。

首先将第一个皇后放于第一行第一列,然后开始向下一行递归。

每一步递归中,首先检测待放置位置是否与已放置的皇后冲突,如不冲突,则进行下一行的放置,否则,选择该行的下一个位置进行检测。

如整行的位置都冲突,则回到上一行,重新选择位置。

1.采用类语言定义相关的数据类型

typedefcharVerT;

#defineMaxSize100

#defineMaxVertices10

#defineMaxWeight10000

#defineN7

typedefintDataType;

typedefstruct{

DataTypelist[MaxSize];

intsize;

}SeqList;

2.算法设计

A、数据初始化。

B、从n列开始摆放第n个皇后(因为这样便可以符合每一竖列一个皇后的要求),先测试当前位置(n,m)是否等于0(未被占领)。

如果是,摆放第n个皇后,并宣布占领(记得姚横列竖列斜列一起设置),接着进行递归;如果不是,测试下一个位置(n,m+1),但是如果当n<=8,m=8时,发现此时已无法摆放时,便要进行回溯。

从问题的某一种可能出发,搜索从这种情况能出发,继续搜索,这种不断“回溯”的寻找解的方法,称为“回溯法”。

C、使用数组实现回溯法的思想。

D、当n>8时,便打印出结果。

E、输出函数我使用printf输出,运行形式为:

第m种方法为:

********

3.函数的调用关系图

4.调试分析

在完整程序调试时遇到几个小问题,后经细心改正后才把调试工作做完。

例如:

当用printf输出时,出现了一些错误,几经调试后,发现原来是缺少了stdio.h这样一个头文件,添加了头文件后,还出现了一些问题,逻辑错误导致程序死循环或不循环或循环一小部分,但是编译时却没有错误,就是没有正确的输出答案,一开始我也不知道是怎么回事,通过和同学的交流,发现是逻辑错误,经过改正后,程序终于可以运行了.时间复杂度O(n^2)空间复杂度

(1),

5.测试结果

6.源程序(带注释)

#include

#include

#include

#include

#include

#defineQUEENS8

intiCount=0;//!

记录解的序号的全局变量。

intSite[QUEENS];//!

记录皇后在各行上的放置位置的全局数组。

voidQueen(intn);//!

递归求解的函数。

voidOutput();//!

输出一个解。

intIsValid(intn);

//!

判断第n个皇后放上去之后,是否有〉冲突。

voidmain()/*----------------------------Main:

主函数。

----------------------------*/

{system("title叶青--递归算法八皇后问题");

cout<<""<<"八皇后的解法:

"<

cout<<""<<"-------------------------------------"<

Queen(0);//!

从第0行开始递归试探。

getch();//!

按任意键返回。

}

voidQueen(intn)/*-----------------Queen:

递归放置第n个皇后,程序的核心!

----------------*/

{inti;

if(n==QUEENS)//!

参数n从0开始,等于8时便试出了一个解,将它输出并回溯。

{Output();return;}

for(i=1;i<=QUEENS;i++)//!

n还没到8,在第n行的各个行上依次试探。

{Site[n]=i;//!

在该行的第i行上放置皇后。

if(IsValid(n))//!

如果放置没有冲突,就开始下一行的试探。

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

当前位置:首页 > 高等教育 > 艺术

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1