算法与数据结构.docx
《算法与数据结构.docx》由会员分享,可在线阅读,更多相关《算法与数据结构.docx(30页珍藏版)》请在冰豆网上搜索。
算法与数据结构
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集合容量加1printf("%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;}elseflag=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){//处理序号1inti;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){//处理序号2printf("-------查看元素-------\n");printf("集合L1:");ErgList(L1);printf("集合L2:");ErgList(L2);printf("----------------------\n");}voidoperate3(SqList*L1,SqList*L2,SqList*L3){//处理序号3inti,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]);elsecontinue;}}}printf("-------求并集结果-------\n");ErgList(L3);printf("-----------------------\n");}voidoperate4(SqList*L1,SqList*L2,SqList*L3){//处理序号4inti,j;ElemTyperes_date;InitList(L3);//初始化L3for(i=0;ilength;i++){//将属于L1同时也属于L2的元素赋值给L3res_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){//处理序号5inti,j;ElemTyperes_date;InitList(L3);//初始化L3for(i=0;ilength;i++){//将属于L1但不属于L2的元素赋值给L3res_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++;}elsecontinue;}}}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,L3InitList(&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#includeintkey()//求方程的解找到解返回否则返回{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;elsereturn0;}intmain(){if(key()==0)printf("方程A^5+B^5+C^5+D^5+E^5=F^5(0<=A<=Breturn1;}四.图的基本操作与实现(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 邻接表 :一种链式存储结构在邻接
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里面
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);//右孩子
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){//处理序号1inti;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){//处理序号2printf("-------查看元素-------\n");printf("集合L1:");ErgList(L1);printf("集合L2:");ErgList(L2);printf("----------------------\n");}voidoperate3(SqList*L1,SqList*L2,SqList*L3){//处理序号3inti,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]);elsecontinue;}}}printf("-------求并集结果-------\n");ErgList(L3);printf("-----------------------\n");}voidoperate4(SqList*L1,SqList*L2,SqList*L3){//处理序号4inti,j;ElemTyperes_date;InitList(L3);//初始化L3for(i=0;ilength;i++){//将属于L1同时也属于L2的元素赋值给L3res_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){//处理序号5inti,j;ElemTyperes_date;InitList(L3);//初始化L3for(i=0;ilength;i++){//将属于L1但不属于L2的元素赋值给L3res_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++;}elsecontinue;}}}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,L3InitList(&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#includeintkey()//求方程的解找到解返回否则返回{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;elsereturn0;}intmain(){if(key()==0)printf("方程A^5+B^5+C^5+D^5+E^5=F^5(0<=A<=Breturn1;}四.图的基本操作与实现(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 邻接表 :一种链式存储结构在邻接
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];
}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{//如果在表尾插入
voidErgList(SqList*L){//遍历线性表并依次返回元素
intj;
ElemTyperes_date;
for(j=0;jlength;j++){
res_date=L->data[j];
printf("%4d",res_date);
////////////////该程序的操作函数/////////////////////////////////
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{
exit();
voidoperate1(SqList*L1,SqList*L2){//处理序号1
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中的元素(仅限整数):
for(i=0;i<5;i++){//接受集合L2的元素
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中且无重复元素
if(L3->data[j]==L2->data[i])//选择存在于L2但不存在于L3的元素
if(j==L3->length-1)
ListInsert(L3,L3->length+1,L2->data[i]);
continue;
printf("-------求并集结果-------\n");
ErgList(L3);
printf("-----------------------\n");
voidoperate4(SqList*L1,SqList*L2,SqList*L3){//处理序号4
for(i=0;ilength;i++){//将属于L1同时也属于L2的元素赋值给L3
res_date=L1->data[i];
if(res_date==L2->data[j]){
L3->data[L3->length]=res_date;
L3->length++;
printf("-------求交集结果-------\n");
voidoperate5(SqList*L1,SqList*L2,SqList*L3){//处理序号5
for(i=0;ilength;i++){//将属于L1但不属于L2的元素赋值给L3
if(j==L2->length-1){
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);
gotostart;
case2:
operate2(&L1,&L2);
printf(">>>元素查看成功!
case3:
operate3(&L1,&L2,&L3);
printf(">>>L1与L2求并集成功!
case4:
operate4(&L1,&L2,&L3);
printf(">>>L1与L2求交集成功!
case5:
operate5(&L1,&L2,&L3);
printf(">>>L1与L2求差集成功!
case6:
operate6(&L1,&L3);
printf(">>>求L1的冥集成功!
case7:
operate7(&L2,&L3);
printf(">>>求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;
printf("EnterN:
scanf("%d",&N);
printf("%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的所有可能的整数解。
运行结果:
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);
if(flag==1)
intmain()
if(key()==0)
printf("方程A^5+B^5+C^5+D^5+E^5=F^5(0<=A<=Breturn1;}四.图的基本操作与实现(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 邻接表 :一种链式存储结构在邻接
四.图的基本操作与实现
(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 邻接表 :
一种链式存储结构
在邻接
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1