算法与数据结构.docx
- 文档编号:12156986
- 上传时间:2023-04-17
- 格式:DOCX
- 页数:39
- 大小:307.55KB
算法与数据结构.docx
《算法与数据结构.docx》由会员分享,可在线阅读,更多相关《算法与数据结构.docx(39页珍藏版)》请在冰豆网上搜索。
算法与数据结构
数据结构与算法课程设计
题目:
集合运算问题;计算1的个数问题;八皇后问题;构造可以使n个城市连接的最小生成树问题
目录
摘要13
一.集合运算问题14
1.采用类语言定义相关的数据类型14
2.算法设计14
3.函数的调用关系图15
4.调试分析15
5.测试结果:
15
6.源程序(带注释)17
二.计算1的个数问题22
1.采用类语言定义相关的数据类型22
2.算法设计22
3.函数的调用关系图22
4.调试分析23
5.测试结果23
6.源程序(带注释)24
三.八皇后问题26
1.采用类语言定义相关的数据类型26
2.算法设计26
3.函数的调用关系图28
4.调试分析29
5.测试结果30
6.源程序(带注释)31
四.构造可以使n个城市连接的最小生成树问题34
1.采用类语言定义相关的数据类型34
2.算法设计35
3.函数的调用关系图36
4.调试分析37
5.测试结果38
6.源程序(带注释)41
参考文献48
致谢49
摘要
本程序主要解决集合运算问题,计算1的个数问题,八皇后问题,n个城市最小生成树问题,设计一个程序,实现两个集合的并集、交集、差集、显示输出等,要求结果集合中的元素不重复;实现一个集合的幂集的求解。
编写递归程序,返回十进制数N的二进制表示中1的个数编写
计算机可以直接识别的语言是机器语言,而机器语言在计算机中的主要表现形式是二进制数,为了能够方便这两者之间的转换,为十进制数和二进制树之间搭建一个桥梁,我们编写了这样一个程序。
将十进制数转换为二进制数并返回十进制数N的二进制表示中1的个数。
程序实现将八个皇后放置在国际象棋棋盘的无冲突的位置上的算法,并给出所有的解。
给定一个地区的n个城市间的距离网,用Prim算法或Kruskal算法建立最小生成树,并计算得到的最小生成树的代价
关键词:
集合的运算计算1的个数八皇后最小生成树
一.集合运算问题
设计一个程序,实现两个集合的并集、交集、差集、显示输出等,要求结果集合中的元素不重复;实现一个集合的幂集的求解。
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;i
res_date=L1->data[i];
for(j=0;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;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;i
for(j=0;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;i
res_date=L1->data[i];
for(j=0;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;i
res_date=L1->data[i];
for(j=0;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的个数问题
编写递归程序,返回十进制数N的二进制表示中1的个数。
1.采用类语言定义相关的数据类型
intn整形变量n为输入的十进制数;inti整形变量i为十进制数的二进制形式中1的个数。
2.算法设计
输入一个N
若为1,n=1;
奇数情况,它的二进制中1的个数等于N/2的二进制中1的个数加1;
偶数情况,N是奇数,N-1是偶数,比N少一个最低位的1,1的个数就是N/2的二进制中1的个数
3.
函数的调用关系图
4.调试分析
(a)、调试中遇到的问题及对问题的解决方法;
刚开始在调试过程中,程序只能把十进制数转化为二进制数,但是却不能统计一的个数,原因是主函数没有调用统计一的个数的那个函数,后来又从书上查看了函数的调用关系,就能执行了。
(b)、算法的时间复杂度和空间复杂度。
算法的时间复杂度T(n)=O(n)
算法的空间复杂度S(n)=O(n)
5.测试结果
6.源程序(带注释)
//getber.h
#ifndefGETBER_H_INCLUDED
#defineGETBER_H_INCLUDED
classGetber
{
public:
voidstoreRadius(intnewNumber);
intcountNumber();
private:
intnumber;
intgo;
intleft;
intcount;
};
#endif//GETBER_H_INCLUDED
//getber.cpp
#include"Getber.h"
#include
usingnamespacestd;
voidGetber:
:
storeRadius(intnewNumber)//获取输入的数字
{
number=newNumber;
}
intGetber:
:
countNumber()
{count=0;
while((go-left)!
=-1)
{
go=number/2;
left=number%2;
number=go;
if(left)
{
count+=1;
}
//cout<<(go-left)<<'\t'< } returncount; } //main.cpp #include usingnamespacestd; intmain() { intptr; GetberGetberInstance; cout<<"输入十进制数: "; cin>>ptr; GetberInstance.storeRadius(ptr); cout<<'\n'; cout<<"十进制转二进制中二进制中‘1’的数目: " < inti; cin>>i; } 三.八皇后问题 要求编写程序实现将八个皇后放置在国际象棋棋盘的无冲突的位置上的算法,并给出所有的解。 提示: 在国际象棋上放置皇后时,任何一个皇后的水平、竖直和斜45º都不能有另一个皇后。 解决该问题采用逐次试探的方法,即采用递归调用putchess函数的方法。 1.采用类语言定义相关的数据类型 数组a[I]: a[I]表示第I个皇后放置的列;I的范围: 1..8; 对角线数组: b[j](主对角线),c[j](从对角线),根据程序的运行,去决定主从对角线是否放入皇后; 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))//! 如果放置没有冲突,就开始下一行的试探。 Queen(n+1);}} intIsValid(intn)/*------IsValid: 判断第n个皇后放上去之后,是否合法,即是否无冲突。 ------*/ {inti; for(i=0;i 将第n个皇后的位置依次于前面n-1个皇后的位置比较。 {if(Site[i]==Site[n])//! 两个皇后在同一列上,返
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 数据结构