算法与数据结构Word格式文档下载.docx
- 文档编号:18658699
- 上传时间:2022-12-31
- 格式:DOCX
- 页数:30
- 大小:272.46KB
算法与数据结构Word格式文档下载.docx
《算法与数据结构Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《算法与数据结构Word格式文档下载.docx(30页珍藏版)》请在冰豆网上搜索。
关键词:
集合,单链表,递归,替换,连通图,方程求解,数据结构,图的遍历
一.集合运算问题
设计一个程序,实现两个集合的并集、交集、差集、显示输出等,要求结果集合中的元素不重复;
实现一个集合的幂集的求解。
1.采用类语言定义相关的数据类型
定义一个结构体存储结构,用来生成求幂集的二叉树只在求幂集函数内使用
typedefstruct//根节点结构体(幂集使用)
{
intdata[MAX];
intlength;
}root;
定义一个二维数组,用来存储节点选择情况,其第一个下标表示是左孩子还是右孩子,第二个表示节点当前所处的层数
intc[2][MAX];
//c构造数据池
2.算法设计
1.并集:
用两个循环结构为并集赋值,最后进行重复元素检查(check())。
for(i=0;
i<
n;
i++)//A集合赋值
{
c[i]=a[i];
}
for(i=0;
=m;
i++)//B集合赋值
c[n+i]=b[i];
}
k=n+m;
//集合大小
k=check(c,k);
//集合重复元素检查
2.利用双重循环判断元素是否在A、B里面均存在,存在则赋值在C里面
=n;
i++)//在A里面检查
for(j=0;
j<
j++)//在B里面检查
if(a[i]==b[j])//元素在A和B里面均出现
c[k]=a[i];
//赋值
k++;
//C集合容量加1
printf("
%d"
c[k-1]);
//屏幕输出
3.利用双重循环判断只在A里面出现过的元素,并把它们赋值到C里面
if(a[i]==b[j])//两个集合都有直接退出循环
flag=0;
//更改标志
break;
else
flag=1;
if(flag)//通过标识检查
c[k]);
}
4.利用二叉树的思想求解幂集,我们认为根节点为空集,然后每一层向树里面加一个元素,直到集合中所有元素添加完毕,在具体每一层中,上一层的叶子节点会有两个孩子,左孩子表示有这一层的元素,右孩子没有,这样的话通过最后一层的叶子节点的扫描就可以得到所有幂集
shu(intn,root*b,intd,intk)/*递归建树*/
inti;
b->
data[k]=d;
length++;
if(k<
=n)//递归建树
shu(n,b,c[1][k],k);
//左孩子
shu(n,b,-1,k);
//右孩子
{"
);
k;
i++)
if(b->
data[i]!
=-1)
%d"
b->
data[i]);
}"
\n"
return0;
}
3.函数的调用关系图
4.调试分析
a、输入集合数据的时候必须要一个一个输,不能依次输入很多,否则会引起错误
b、算法的时间复杂度O(n^2)。
5.测试结果
输入集合:
并集:
交集:
差集:
6.源程序(带注释)
#include<
stdio.h>
#defineMAXSIZE10//线性表的最大长度
typedefintElemType;
typedefstruct{//线性表的结构体
ElemTypedata[MAXSIZE];
}SqList;
////////////////线性表的操作函数//////////////////////////////
voidInitList(SqList*L){//初始化线性表
L->
data==NULL;
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;
return1;
else{//如果在表尾插入
voidErgList(SqList*L){//遍历线性表并依次返回元素
intj;
ElemTyperes_date;
L->
length;
j++){
res_date=L->
data[j];
printf("
%4d"
res_date);
////////////////该程序的操作函数/////////////////////////////////
intmenu(){//菜单函数
intm_cho;
system("
cls"
--------MENU--------\n"
1->
给集合L1和集合L2添加元素\n"
2->
查看集合L1,L2\n"
3->
求L1与L2的并集\n"
4->
求L1与L2的交集\n"
5->
求L1与L2的差集\n"
6->
求L1的冥集\n"
7->
求L2的冥集\n"
8->
退出系统\n"
--------------------\n"
--请输入序号:
[]\b\b"
scanf("
%d"
&
m_cho);
if(1<
=m_cho&
&
m_cho<
=6)
returnm_cho;
else{
system("
exit();
return0;
voidoperate1(SqList*L1,SqList*L2){//处理序号1
ElemTypeins_e[5];
请输入集合L1中的元素(仅限整数):
5;
i++){//接受集合L1的元素
scanf("
ins_e[i]);
ListInsert(L1,i+1,ins_e[i]);
请输入集合L2中的元素(仅限整数):
i++){//接受集合L2的元素
ListInsert(L2,i+1,ins_e[i]);
voidoperate2(SqList*L1,SqList*L2){//处理序号2
-------查看元素-------\n"
集合L1:
"
ErgList(L1);
集合L2:
ErgList(L2);
----------------------\n"
voidoperate3(SqList*L1,SqList*L2,SqList*L3){//处理序号3
inti,j;
InitList(L3);
//初始化L3
*L3=*L1;
L2->
i++){//将L2中的元素放入L3中且无重复元素
for(j=0;
L3->
j++){
if(L3->
data[j]==L2->
data[i])//选择存在于L2但不存在于L3的元素
break;
else{
if(j==L3->
length-1)
ListInsert(L3,L3->
length+1,L2->
else
continue;
}
-------求并集结果-------\n"
ErgList(L3);
-----------------------\n"
voidoperate4(SqList*L1,SqList*L2,SqList*L3){//处理序号4
//初始化L3
L1->
i++){//将属于L1同时也属于L2的元素赋值给L3
res_date=L1->
data[i];
if(res_date==L2->
data[j]){
L3->
data[L3->
length]=res_date;
-------求交集结果-------\n"
voidoperate5(SqList*L1,SqList*L2,SqList*L3){//处理序号5
i++){//将属于L1但不属于L2的元素赋值给L3
if(j==L2->
length-1){
L3->
}
-------求差集结果-------\n"
voidoperate6(SqList*L1,SqList*L3){//处理序号6
voidoperate7(SqList*L2,SqList*L3){//处理序号7
intmain(){
intc;
charres;
SqListL1,L2,L3;
//定义线性表L1,L2,L3
InitList(&
L1);
//初始化线性表
L2);
L3);
start:
c=menu();
switch(c){//处理所选的操作
case1:
{
operate1(&
L1,&
printf("
>
元素输入成功!
0_0\n"
按ENTER键返回..."
scanf("
%c"
res);
gotostart;
case2:
operate2(&
元素查看成功!
case3:
operate3(&
L2,&
L1与L2求并集成功!
case4:
operate4(&
L1与L2求交集成功!
case5:
operate5(&
L1与L2求差集成功!
case6:
operate6(&
求L1的冥集成功!
case7:
operate7(&
求L2的冥集成功!
2.计算1的个数问题
计算1的个数问题。
编写递归程序,返回十进制数N的二进制表示中1的个数。
1.数据结构
intcount()/*计算1的个数*/
longN;
/*输入的十进制数*/
intcount(longN)/*计算1的个数*/
if(N==0)
elseif(N%2==1)
return(count(N/2)+1);
elsereturncount(N/2);
3.调试分析
4.测试结果
5.源程序(带注释)
#include"
stdio.h"
voidmain()
longN;
EnterN:
N);
%d\n"
count(N));
三.方程求解问题
方程A5+B5+C5+D5+E5=F5刚好有一个满足0≤A≤B≤C≤D≤E≤F≤75的整数解。
请编写一个求出该解的程序。
将ABCDEF的五次方的值储存在数组p[]中
首先建立数组,用来存储整型ABCDEF五次方的值,然后利用fo嵌套循环,一次求ABCDEF五次方的值,接下来用if判断语句,若ABCDE次方之和与F五次方的差为零,输出ABCDEF的整数解。
3.函数的调用关系图
运行程序,是否可以输出ABCDEF的整数解。
程序没有什么大问题,可以直接运行,调试之后运行直接将小于75的所有可能整数解全部给出来。
可以输出ABCDEF的所有可能的整数解。
运行结果:
math.h>
intkey()
//求方程的解找到解返回否则返回
longp[76];
longA,B,C,D,E,F,i,flag=0;
=75;
i++)
p[i]=int(pow(i,5));
//把—的次方放在数组中,以便调用
for(A=0;
A<
=60;
A++)
//循环穷举找到方程的解
for(B=A;
B<
B++)
for(C=B;
C<
C++)
for(D=C;
D<
D++)
for(E=D;
E<
E++)
for(F=E;
F<
F++)
if(p[A]+p[B]+p[C]+p[D]+p[E]-p[F]==0)
{
\t\t\t%d^5+%d^5+%d^5+%d^5+%d^5=%d^5\n\n"
A,B,C,D,E,F);
\t\t\t%d%d%d%d%d%d\n\n"
if(flag==1)
return1;
intmain()
{
if(key()==0)
方程A^5+B^5+C^5+D^5+E^5=F^5(0<
=A<
=B<
=D<
=E<
=F<
=75)无解"
四.图的基本操作与实现
(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
邻接矩阵
:
适用于图中边或弧的数目比较多的情况,压缩存储方式结构。
邻接矩阵是表示顶点之间相邻关系的矩阵。
若图有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
邻接表
一种链式存储结构
在邻接
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 数据结构