算法与数据结构.docx

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

算法与数据结构.docx

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

算法与数据结构.docx

算法与数据结构

2014年秋季学期

数据结构与算法课程设计

题目:

集合运算问题、计算1的个数问题、

方程求解问题、图的基本操作与实现

目录

摘要3

一.集合运算问题4

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

2.算法设计4

3.函数的调用关系图6

4.调试分析7

5.测试结果7

6.源程序(带注释)8

二.计算1的个数问题13

1.数据结构13

2.算法设计14

3.调试分析14

4.测试结果14

5.源程序(带注释)14

三.方程求解问题15

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

2.算法设计15

3.函数的调用关系图15

4.调试分析15

5.测试结果16

6.源程序(带注释)16

四.图的基本操作与实现......................................................................................17

1.数据结构...............................................................................................18

2.算法设计...............................................................................................18

3.运行结果................................................................................................20

4.源程序(带注释)....................................................................................20

总结25

参考文献26

致谢26

摘要

第一个程序是编写算法实现集合的相关操作包括集合的输入、输出、删除集合中重复的元素、删除、修改,求两个集合的交、并、差。

采用单链表对集合进行操作、运行等。

需要用到二叉树思想、便利线性表和双重循环结构等完成问题。

第二个程序是递归结构计算1的个数问题,共分为两种情况,奇数情况和偶数情况。

第三个程序为方程求解问题,用c语言实现方程A5+B5+C5+D5+E5=F5刚好有一个满足0≤A≤B≤C≤D≤E≤F≤75的整数解的问题。

也可以将生活中的实际问题转换成此类方程的求解,这样进行程序的迭代和功能的更新,就可以实现更多未知数、更高次、更多解的方程求解问题,和涉及此类方程求解的实际问题。

第四个程序为图的一些基本操作,内容包括图的存储结构、图的深度优先遍历,广度优先遍历,图节点的度数等等。

 

关键词:

集合,单链表,递归,替换,连通图,方程求解,数据结构,图的遍历

 

一.集合运算问题

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

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

定义一个结构体存储结构,用来生成求幂集的二叉树只在求幂集函数内使用

typedefstruct//根节点结构体(幂集使用)

{

intdata[MAX];

intlength;

}root;

定义一个二维数组,用来存储节点选择情况,其第一个下标表示是左孩子还是右孩子,第二个表示节点当前所处的层数

intc[2][MAX];//c构造数据池

2.算法设计

1.并集:

用两个循环结构为并集赋值,最后进行重复元素检查(check())。

for(i=0;i

{

c[i]=a[i];

}

for(i=0;i<=m;i++)//B集合赋值

{

c[n+i]=b[i];

}

k=n+m;//集合大小

k=check(c,k);//集合重复元素检查

2.利用双重循环判断元素是否在A、B里面均存在,存在则赋值在C里面

for(i=0;i<=n;i++)//在A里面检查

for(j=0;j<=m;j++)//在B里面检查

{

if(a[i]==b[j])//元素在A和B里面均出现

{

c[k]=a[i];//赋值

k++;//C集合容量加1

printf("%d",c[k-1]);//屏幕输出

}

}

3.利用双重循环判断只在A里面出现过的元素,并把它们赋值到C里面

for(i=0;i<=n;i++)//在A里面检查

{

for(j=0;j<=m;j++)//在B里面检查

{

if(a[i]==b[j])//两个集合都有直接退出循环

{

flag=0;//更改标志

break;

}

else

flag=1;

}

if(flag)//通过标识检查

{

c[k]=a[i];

printf("%d",c[k]);

}

}

4.利用二叉树的思想求解幂集,我们认为根节点为空集,然后每一层向树里面加一个元素,直到集合中所有元素添加完毕,在具体每一层中,上一层的叶子节点会有两个孩子,左孩子表示有这一层的元素,右孩子没有,这样的话通过最后一层的叶子节点的扫描就可以得到所有幂集

shu(intn,root*b,intd,intk)/*递归建树*/

{

inti;

b->data[k]=d;

b->length++;

k++;

if(k<=n)//递归建树

{

shu(n,b,c[1][k],k);//左孩子

shu(n,b,-1,k);//右孩子

}

else

{

printf("{");

for(i=0;i

{

if(b->data[i]!

=-1)

printf("%d",b->data[i]);

}

printf("}");

printf("\n");

}

return0;

}

3.函数的调用关系图

 

4.调试分析

a、输入集合数据的时候必须要一个一个输,不能依次输入很多,否则会引起错误

 

b、算法的时间复杂度O(n^2)。

5.测试结果

输入集合:

并集:

交集:

差集:

6.源程序(带注释)

#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;

}

2.计算1的个数问题

计算1的个数问题。

编写递归程序,返回十进制数N的二进制表示中1的个数。

1.数据结构

intcount()/*计算1的个数*/

longN;/*输入的十进制数*/

2.算法设计

intcount(longN)/*计算1的个数*/

{

if(N==0)

return0;

elseif(N%2==1)

return(count(N/2)+1);

elsereturncount(N/2);

}

3.调试分析

4.测试结果

5.源程序(带注释)

#include"stdio.h"

intcount(longN)/*计算1的个数*/

{

if(N==0)

return0;

elseif(N%2==1)

return(count(N/2)+1);

elsereturncount(N/2);

}

voidmain()

{

longN;

printf("EnterN:

");

scanf("%d",&N);

printf("%d\n",count(N));

}

 

三.方程求解问题

方程A5+B5+C5+D5+E5=F5刚好有一个满足0≤A≤B≤C≤D≤E≤F≤75的整数解。

请编写一个求出该解的程序。

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

将ABCDEF的五次方的值储存在数组p[]中

2.算法设计

首先建立数组,用来存储整型ABCDEF五次方的值,然后利用fo嵌套循环,一次求ABCDEF五次方的值,接下来用if判断语句,若ABCDE次方之和与F五次方的差为零,输出ABCDEF的整数解。

3.函数的调用关系图

 

4.调试分析

运行程序,是否可以输出ABCDEF的整数解。

程序没有什么大问题,可以直接运行,调试之后运行直接将小于75的所有可能整数解全部给出来。

5.测试结果

可以输出ABCDEF的所有可能的整数解。

运行结果:

6.源程序(带注释)

 

#include

#include

intkey()

//求方程的解找到解返回否则返回

{

longp[76];

longA,B,C,D,E,F,i,flag=0;

for(i=0;i<=75;i++)

p[i]=int(pow(i,5));

//把—的次方放在数组中,以便调用

for(A=0;A<=60;A++)

//循环穷举找到方程的解

for(B=A;B<=75;B++)

for(C=B;C<=75;C++)

for(D=C;D<=75;D++)

for(E=D;E<=75;E++)

for(F=E;F<=75;F++)

if(p[A]+p[B]+p[C]+p[D]+p[E]-p[F]==0)

{

printf("\t\t\t%d^5+%d^5+%d^5+%d^5+%d^5=%d^5\n\n",A,B,C,D,E,F);

printf("\t\t\t%d%d%d%d%d%d\n\n",A,B,C,D,E,F);

flag=1;

}

if(flag==1)

return1;

else

return0;

}

intmain()

{

if(key()==0)

printf("方程A^5+B^5+C^5+D^5+E^5=F^5(0<=A<=B

return1;

}

四.图的基本操作与实现

(1)自选存储结构,输入含n个顶点(用字符表示顶点)和e条边的图G;

(2)求每个顶点的度,输出结果;

(3)指定任意顶点x为初始顶点,对图G作DFS遍历,输出DFS顶点序列(提示:

使用一个栈实现DFS);

(4)指定任意顶点x为初始顶点,对图G作BFS遍历,输出BFS顶点序列(提示:

使用一个队列实现BFS);

(5)输入顶点x,查找图G:

若存在含x的顶点,则删除该结点及与之相关连的边,并作DFS遍历(执行操作3);否则输出信息“无x”;

(6)判断图G是否是连通图,输出信息“YES”/“NO”;

(7)如果选用的存储结构是邻接矩阵,则用邻接矩阵的信息生成图G的邻接表,即复制图G,然再执行操作

(2);反之亦然。

1.数据结构

1 邻接矩阵 :

适用于图中边或弧的数目比较多的情况,压缩存储方式结构。

邻接矩阵是表示顶点之间相邻关系的矩阵。

若图有n个顶点,则邻接矩阵是一个n*n阶的方阵,结构唯一。

邻接矩阵A的元素规定为:

用邻接矩阵存储网时只需要将矩阵中的1换为相应的权值,将0用一个不可能存在的权值代替即可。

当图用邻接矩阵表示后图的某些操作的实现是很方便的,如求某一顶点vi的第一邻接点,只需在第i行找到第1个非零元即可。

若求某一顶点vi的度,对于无向图来说,只须统计第i行的非零元个数或第i列的非零元个数(无向图的邻接矩阵是对称的);当图中顶点数确定,插入一条边(vi,vj)只须将矩阵中第i行j列和第j行i列的元素分别改为1或相应的权值;插入一条弧i,vj>只须将矩阵中第i行j列的元素改为1或相应的权值即可。

2 邻接表 :

一种链式存储结构

在邻接

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

当前位置:首页 > 自然科学 > 生物学

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

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