数据结构-实验六讲义(1)-图的基本操作

合集下载

数据结构与算法实验——图的基本操作

数据结构与算法实验——图的基本操作

数据结构与算法实验——图的基本操作图的基本操作实验报告图的基本操作实验报告实验名称图的基本操作实验目的1.掌握图的各种存储结构,特别要熟练掌握邻接矩阵和邻接表的存储结构;2.遍历是图各种应用的算法的基础,要熟练掌握图的深度优先遍历和广度优先遍历的算法,复习栈和队列的应用;3.掌握以邻接矩阵作为存储结构的生成图的最小生成树的普利姆算法;实验内容编制一个演示图的邻接表的创建、深度遍历、广度遍历操作的程序。

问题描述用数据结构相关知识,实现邻接表的定义和操作。

该程序包括图的邻接表的结点类型定义以及对图操作的具体的函数定义(包括:建立图的邻接表、深度优先遍历图、广度优先遍历图)。

问题分析该实验是基于C语言和数据结构知识基础的对图的基本操作的检验,无需设计复杂的算法,程序语句也相对简单。

因此,我直接按要求定义了对图操作的具体函数,并于主函数中实现对应的功能调用。

实验步骤1.需求分析本演示程序用VC++编写,完成图的邻接表的生成、遍历基本操作。

输入的形式和输入值的范围:在输入邻接表顶点信息前,必须先确定该信息能正确创建邻接表。

②输出的形式:在所有三种操作中都显示操作是否正确以及操作后图的内容。

③程序所能达到的功能:完成图的邻接表的生成、深度优先遍历、广度优先遍历基本操作。

④测试数据:创建操作中依次输入7,7作为顶点数和边数,以(0,1)(0,2)(1,3)(1,5)(3,4)(3,6)(4,5)作为各顶点信息生成一个邻接表。

2.概要设计1)为了实现上述程序功能,需要定义二叉树的抽象数据类型:ADT Graph {数据对象:顶点的有穷非空集合和边的集合数据关系:结点具有相同的数据类型及层次结构基本操作:Void InitGraph(ALGraph *G)初始条件:无操作结果:初始化图Void DFSTraverse(ALGraph *G)初始条件:图Graph已存在操作结果:按深度优先遍历图的邻接表Void BFSTraverse(ALGraph *G)初始条件:图Graph已存在操作结果:按广度优先遍历图的邻接表2)本程序包含7个函数:①主函数main() ②建立一个图的邻接表函数CreateGraphAL ()③深度优先遍历图 DFS ()④广度优先遍历 BFS()函数说明#include <stdio.h>#include <stdlib.h>#define MaxVertexNum 100#define QueueSize 30typedef enum{FALSE,TRUE}Boolean;Boolean visited[MaxVertexNum];typedef char VertexType;typedef int EdgeType;typedef struct node //边表结点{int adjvex; //邻接点域struct node *next; //域链//若是要表示边上的权,则应增加一个数据域}EdgeNode;typedef struct vnode //顶点边结点{VertexType vertex; //顶点域EdgeNode *firstedge;//边表头指针}VertexNode;typedef VertexNode AdjList[MaxVertexNum];//AdjList是邻接表类型typedef struct{AdjList adjlist; //邻接表int n,e; //图中当前顶点数和边数}ALGraph;void CreateGraphAL (ALGraph *G){int i,j,k;EdgeNode * s;printf("请输入顶点数和边数(输入格式为:顶点数,边数):\n");scanf("%d,%d",&(G->n),&(G->e));// 读入顶点数和边数printf("请输入顶点信息(输入格式为:顶点号<CR>)每个顶点以回车作为结束:\n");for (i=0;i<G->n;i++) //立有n个顶点的顶点表{scanf("\n%c",&(G->adjlist[i].vertex)); //读入顶点信息G->adjlist[i].firstedge=NULL; // 点的边表头指针设为空}printf("请输入边的信息(输入格式为:i,j):\n");for (k=0;k<G->e;k++) // 建立边表{scanf("\n%d,%d",&i,&j); // 读入边<Vi,Vj>的顶点对应序号s=new EdgeNode; // 生成新边表结点ss->adjvex=j; // 邻接点序号为js->next=G->adjlist[i].firstedge; // 将新边表结点s插入到顶点Vi的边表头部 G->adjlist[i].firstedge=s;s=new EdgeNode;s->adjvex=i;s->next=G->adjlist[j].firstedge;G->adjlist[j].firstedge=s;}}/**************************************** ********************************//* 深度优先遍历*//**************************************** ********************************/void DFS(ALGraph *G,int i){//以vi为出发点对邻接表表示的图G进行深度优先搜索EdgeNode *p;printf("visitvertex:%c\n",G->adjlist[i].vertex); // 访问顶点vivisited[i]=TRUE; //标记vi已访问p=G->adjlist[i].firstedge; //取vi 边表的头指针while(p){ //依次搜索vi的邻接点vj,这里j=p->adjvexif (!visited[p->adjvex]) //若vi尚未被访问DFS(G,p->adjvex); //则以Vj为出发点向纵深搜索p=p->next; //找vi的下一邻接点}}void DFSTraverseM(ALGraph *G){int i;for(i=0;i<G->n;i++)visited[i]=FALSE;for(i=0;i<G->n;i++)if(!visited[i])DFS(G,i);}/**************************************** ********************************//* 广度优先遍历*//**************************************** ********************************/ typedef struct{int front;int rear;int count;int data[QueueSize];}CirQueue;void InitQueue(CirQueue *Q){Q->front=Q->rear=0;Q->count=0;}int QueueEmpty(CirQueue *Q){return Q->front==Q->rear;}int QueueFull(CirQueue *Q){return(Q->rear+1)%QueueSize==Q->front; }void EnQueue(CirQueue *Q,int x) {if (QueueFull(Q))printf("Queue overflow"); else{Q->count++;Q->data[Q->rear]=x;Q->rear=(Q->rear+1)%QueueSize; }}int DeQueue(CirQueue *Q){int temp;if(QueueEmpty(Q)){printf("Queue underflow");return false;}else{temp=Q->data[Q->front];Q->count--;Q->front=(Q->front+1)%QueueSize; return temp;}}void BFS(ALGraph*G,int k){ // 以vk为源点对用邻接表表示的图G进行广度优先搜索int i;CirQueue Q; //须将队列定义中DataType改为intEdgeNode *p;InitQueue(&Q); //队列初始化printf("visitvertex:%c\n",G->adjlist[k].vertex); //访问源点vkvisited[k]=TRUE;EnQueue(&Q,k); //vk已访问,将其人队。

实验六 图的基本操作

实验六 图的基本操作

南京信息工程大学实验(实习)报告图的基本操作一、实验目的1、熟悉图的存储结构2、掌握图的基本操作二、实验准备1、奔腾2计算机或以上机型2、Microsoft Visual C++ 6.0三、实验内容1、建立一张图2、实现深度优先搜索、广度优先搜索遍历四、实验代码#include<stdio.h>#include<conio.h>#include<stdlib.h>typedef struct ArcNode{int adjVex;struct ArcNode *nextArc;}ArcNode;typedef struct VNode{int data;ArcNode *firstArc;}VNode;//创建一张图void CreatGraphic();//深度优先搜索遍历void DFSTraverse(int searchNode);//广度优先搜索遍历void BFSTraverse(int searchNode);//访问标志置零void ClearVisited();void Bound(char ch, int num);//邻接表VNode *adjList;//访问标记数组short *visited;//循环队列, 用于广度优先搜索遍历函数中int *queue;//图的结点数int graphicNode;//用于判断是否创建了图bool creatGraphic;int main(void){char choice;int searchNode;creatGraphic = false;while (true){if (!creatGraphic){system("CLS");printf(" 图的操作\n");Bound('-', 15);printf(" 1. 创建一张图\n");printf(" 0. 退出程序\n");Bound('-', 15);printf(" 请选择: ");fflush(stdin);choice = getchar();switch (choice){case '1':CreatGraphic();break;case '0':printf("\n");system("PAUSE");return 0;default:printf("\n 输入错误, 按任意键后重新输入!");getch();break;}}else{system("CLS");printf(" 图的操作\n");Bound('-', 20);printf(" 1. 深度优先搜索遍历\n");printf(" 2. 广度优先搜索遍历\n");printf(" 0. 退出程序\n");Bound('-', 20);printf(" 请选择: ");fflush(stdin);choice = getchar();switch (choice){case '1':ClearVisited();Lable1:printf("\n 请输入起始搜索的结点序号: ");fflush(stdin);scanf("%d", &searchNode);if (searchNode>=1 && searchNode <=graphicNode){printf(" 深度优先搜索遍历为: ");DFSTraverse(searchNode);}else{printf(" 序号输入错误, 按任意键后重新输入! \n");getch();goto Lable1;}printf("\n\n");system("PAUSE");break;case '2':ClearVisited();Lable2:printf("\n 请输入起始搜索的结点序号: ");scanf("%d", &searchNode);if (searchNode>=1 && searchNode <=graphicNode){printf(" 广度优先搜索遍历为: ");BFSTraverse(searchNode);}else{printf(" 序号输入错误, 按任意键后重新输入! \n");getch();goto Lable2;}printf("\n\n");system("PAUSE");break;case '0':printf("\n");system("PAUSE");return 0;default:printf("\n 输入错误, 按任意键后重新输入!");getch();break;}}}}void CreatGraphic(){int number;int localNode, linkNode;ArcNode *tempNode;Flag:printf("\n 请输入图的顶点数: ");fflush(stdin);scanf("%d", &graphicNode);if (graphicNode <= 0){printf(" 输入错误, 按任意键后重新输入!\n");getch();goto Flag;}if ((adjList=(VNode *)malloc(sizeof(VNode)*graphicNode)) == NULL){printf(" 内存空间不足, 无法创建图!\n");system("PAUSE");exit(0);}if ((visited=(short *)malloc(sizeof(short)*graphicNode)) == NULL){printf(" 内存空间不足, 无法创建访问记录表!\n");system("PAUSE");exit(0);}if ((queue=(int *)malloc(sizeof(int)*graphicNode)) == NULL){printf(" 内存空间不足, 无法创建队列!\n");system("PAUSE");exit(0);}for (number=0; number<graphicNode; ++number){adjList[number].data = number + 1;adjList[number].firstArc = NULL;}printf("\n 请输入所要创建的图中所有相关联的顶点, 格式( 图中一顶点与此顶点相关联的顶点)\n");do{printf(" 请输入( 注意: 输入0 0 结束输入): ");fflush(stdin);scanf("%d %d", &localNode, &linkNode);if (localNode>=1 && localNode<=graphicNode && linkNode>=1 && linkNode<=graphicNode){if ((tempNode = (ArcNode *)malloc(sizeof(ArcNode))) == NULL){printf(" 内存不足, 无法创建图!\n");exit(0);}tempNode->adjVex = linkNode;tempNode->nextArc = adjList[localNode - 1].firstArc;adjList[localNode - 1].firstArc = tempNode;}else{creatGraphic = true;return;}}while(true);}void DFSTraverse(int searchNode){ArcNode *tempNode;visited[searchNode - 1] = 1;printf("%d ", searchNode);tempNode = adjList[searchNode - 1].firstArc;while (tempNode != NULL){if (visited[tempNode->adjVex - 1] == 0){DFSTraverse(tempNode->adjVex);}tempNode = tempNode->nextArc;}}void BFSTraverse(int searchNode){ArcNode *tempNode;int nodeNum;int front = 0, rear = 0;printf("%d ", searchNode);visited[searchNode - 1] = 1;rear = (rear + 1) % graphicNode;queue[rear] = searchNode;while (front != rear){front = (front + 1) % graphicNode;nodeNum = queue[front];tempNode = adjList[nodeNum - 1].firstArc;while (tempNode != NULL){if (visited[tempNode->adjVex - 1] == 0){visited[tempNode->adjVex - 1] = 1;printf("%d ", tempNode->adjVex);rear = (rear + 1) % graphicNode;queue[rear] = tempNode->adjVex;}tempNode = tempNode->nextArc;}}}void ClearVisited(){int cnt;for (cnt=0; cnt<graphicNode; ++cnt){visited[cnt] = 0;}}void Bound(char ch, int num){while (num--){putchar(ch);}putchar('\n');}(本次实验中所用图示意图)(图1:按格式创建图)1876 5 4 3 2(图2:深度优先搜索遍历)(图3:广度优先搜索遍历)五、实验总结…。

数据结构图的存储结构及基本操作

数据结构图的存储结构及基本操作

printf("第%d个\n",i+1); scanf("%s",&G.vertices[i]); G.vertices[i].firstarc = NULL; } //这里开始构造边 printf("请输入边的信息\n"); printf("例如:v1 v2\n"); for(i = 0 ; i < G.arcnum ; i++) { printf("第%d条边\n",i+1); scanf("%s %s",&node1,&node2); j = LocateVex(G,node1); k = LocateVex(G,node2); p = (ArcNode *)malloc(sizeof(ArcNode)); q = (ArcNode *)malloc(sizeof(ArcNode)); p->adjvex = k; q->adjvex = j; p->nextarc = G.vertices[j].firstarc; G.vertices[j].firstarc = p; q->nextarc = G.vertices[k].firstarc; G.vertices[k].firstarc = q; } PrintUDG(G); return 1; } int DeleteUDG(ALGraph &G) { int i,j; ArcNode *p,*q; char node[2]; int LocateVex(ALGraph G,char node[2]); void PrintUDG(ALGraph G); if(G.arcnum == 0) { printf("请先生成图\n");

数据结构实验-图的基本操作

数据结构实验-图的基本操作

浙江大学城市学院实验报告课程名称数据结构实验项目名称实验十三/十四图的基本操作学生姓名专业班级学号实验成绩指导老师(签名)日期 2014/06/09一.实验目的和要求1、掌握图的主要存储结构。

2、学会对几种常见的图的存储结构进行基本操作。

二.实验内容1、图的邻接矩阵定义及实现:建立头文件test13_AdjM.h,在该文件中定义图的邻接矩阵存储结构,并编写图的初始化、建立图、输出图、输出图的每个顶点的度等基本操作实现函数。

同时建立一个验证操作实现的主函数文件test13.cpp(以下图为例),编译并调试程序,直到正确运行。

2、图的邻接表的定义及实现:建立头文件test13_AdjL.h,在该文件中定义图的邻接表存储结构,并编写图的初始化、建立图、输出图、输出图的每个顶点的度等基本操作实现函数。

同时在主函数文件test13.cpp中调用这些函数进行验证(以下图为例)。

3、填写实验报告,实验报告文件取名为report13.doc。

4、上传实验报告文件report13.doc到BB。

注: 下载p256_GraphMatrix.cpp(邻接矩阵)和p258_GraphAdjoin.cpp(邻接表)源程序,读懂程序完成空缺部分代码。

三. 函数的功能说明及算法思路(包括每个函数的功能说明,及一些重要函数的算法实现思路)四. 实验结果与分析(包括运行结果截图、结果分析等)五.心得体会程序比较难写,但是可以通过之前的一些程序来找到一些规律(记录实验感受、上机过程中遇到的困难及解决办法、遗留的问题、意见和建议等。

)【附录----源程序】256://p-255 图的存储结构以数组邻接矩阵表示, 构造图的算法。

#include <iostream.h>#include <stdio.h>#include <stdlib.h>#include <string.h>typedef char VertexType; //顶点的名称为字符const int MaxVertexNum=10; //图的最大顶点数const int MaxEdgeNum=100; //边数的最大值typedef int WeightType; //权值的类型const WeightType MaxValue=32767; //权值的无穷大表示typedef VertexType Vexlist[MaxVertexNum]; //顶点信息,定点名称typedef WeightType AdjMatrix[MaxVertexNum][MaxVertexNum]; //邻接矩阵typedef enum{DG,DN,AG,AN} GraphKind; //有向图,有向网,无向图,无向网typedef struct{Vexlist vexs; // 顶点数据元素AdjMatrix arcs; // 二维数组作邻接矩阵int vexnum, arcnum; // 图的当前顶点数和弧数GraphKind kind; // 图的种类标志} MGraph;void CreateGraph(MGraph &G, GraphKind kd)// 采用数组邻接矩阵表示法,构造图G{//构造有向网Gint i,j,k,q;char v, w;G.kind=kd; //图的种类printf("输入要构造的图的顶点数和弧数:\n");scanf("%d,%d",&G.vexnum,&G.arcnum);getchar();//过滤回车printf("依次输入图的顶点名称ABCD...等等:\n");for (i=0; i<G.vexnum; i++) scanf("%c",&G.vexs[i]);//构造顶点数据getchar();//过滤回车for (i=0; i<G.vexnum; i++) //邻接矩阵初始化for (j=0; j<G.vexnum; j++)if(kd==DN||kd==AN)G.arcs[i][j]=MaxValue; //网,初始值为无穷大elseG.arcs[i][j]=0; //图,初始为0if(kd==DN||kd==AN)printf("按照:尾顶点名->头顶点名,权值输入数据:如A->B,23 \n");elseprintf("按照:尾顶点名->头顶点名输入数据:A->B\n");for (k=0; k<G.arcnum; k++){ //构造邻接矩阵if(kd==DN||kd==AN)scanf("%c->%c,%d",&v,&w,&q); //输入弧的两个定点及该弧的权重elsescanf("%c->%c",&v,&w);getchar();for(i=0;i<G.vexnum; i++)if(G.vexs[i]==v) break;//查找出v在vexs[]中的位置iif(i==G.vexnum) {cerr<<"vertex ERROR!";exit(1);} for(j=0;j<G.vexnum; j++)if(G.vexs[j]==w) break;//查找出v在vexs[]中的位置jif(j==G.vexnum) {cerr<<"vertex ERROR!";exit(1);}if(kd==AN)//无向网{G.arcs[i][j]=q; //邻接矩阵对应位置置权值G.arcs[j][i]=q; //无向图为对称矩阵}else if(kd==DN)//有向网G.arcs[i][j]=q;else if(kd==AG)//无向图{G.arcs[i][j]=1; //对称矩阵G.arcs[j][i]=1;}else //有向图G.arcs[i][j]=1;// getchar();}}//CreateGraph/* 注意输入格式,按以下方式输入构造有向网输入要构造的网的顶点数和弧数:4,5依次输入网的顶点名称ABCD...等等:abcd按照:尾顶点名->头顶点名,权值输入数据:如A->B,23 a->b,5a->c,8c->b,7a->d,4d->c,3输出邻接矩阵∞ | 5 | 8 | 4 |∞ | ∞ | ∞ | ∞ |∞ | 7 | ∞ | ∞ |∞ | ∞ | 3 | ∞ |Press any key to continue*/void PrintMGraph(MGraph &G){int i,j;switch(G.kind){case DG:for (i=0; i<G.vexnum; i++){for (j=0; j<G.vexnum; j++)printf(" %2.d | ",G.arcs[i][j]);printf("\n");}break;case DN:for (i=0; i<G.vexnum; i++){for (j=0; j<G.vexnum; j++){if(G.arcs[i][j]!=MaxValue) printf(" %2.d | ",G.arcs[i][j]);else printf(" ∞ | ");}printf("\n");}break;case AG:for (i=0; i<G.vexnum; i++){for (j=0; j<G.vexnum; j++){printf(" %2.d | ",G.arcs[i][j]);}printf("\n");}break;case AN: //********完成构造无向网****************/* 请模仿编写无向网*/for (i=0; i<G.vexnum; i++){for (j=0; j<G.vexnum; j++){if(G.arcs[i][j]!=MaxValue) printf(" %2.d | ",G.arcs[i][j]);else printf(" ∞ | ");}printf("\n");}break;}}//*****************完成函数**********************************void countdig(MGraph G) //请完成计算图的入度或初度{if(G.kind==DG||G.kind==DN){//计算有向图或网的各个顶点的入度与出度int outD,inD;int i,j;for(i=0;i<G.vexnum;i++){outD=inD=0;for(j=0;j<G.vexnum;j++){if(G.arcs[i][j]!=0&&G.arcs[i][j]!=MaxValue)outD++;}for(j=0;j<G.vexnum;j++){if(G.arcs[j][i]!=0&&G.arcs[j][i]!=MaxValue)inD++;}printf("%c:出度是%d,入度是%d\n",G.vexs[i],outD,inD);}}else{// 计算无向图或网的度int i,j;int Du;for(i=0;i<G.vexnum;i++){Du=0;for(j=0;j<G.vexnum;j++){if(G.arcs[i][j]!=0&&G.arcs[i][j]!=MaxValue)Du++;}printf("%c的度是%d\n",G.vexs,Du);}}}//************参照p265设计深度有限搜索***********void DFSMatrix(MGraph G,int i,int n,bool*visited){cout<<G.vexs[i]<<' ';visited[i]=true;for(int j=0;j<n;j++)if(G.arcs[i][j]!=0&&G.arcs[i][j]!=MaxValue&& !visited[j])DFSMatrix(G,j,n,visited);}//************参照p268设计广度有限搜索***********void BFSMatrix(MGraph G,int i, int n , bool*visited){const int MaxSize=30;int q[MaxSize]={0};int front=0,rear=0;cout<<G.vexs[i]<<' ';visited[i]=true;q[++rear]=i;while(front!=rear){front=(front+1)%MaxSize;int k=q[front];for(int j=0;j<n;j++){if(G.arcs[i][j]!=0&&G.arcs[i][j]!=MaxValue&& !visited[j]){cout<<G.vexs[j]<<' ';visited[j]=true;rear=(rear+1)%MaxSize;q[rear=j];}}}}void main(){MGraph G;int k;printf("请选择图的种类:0:有向图,1:有向网,2:无向图,3:无向网. 请选择:");scanf("%d",&k);switch(k) { //DG,DN,AG,ANcase 0:printf("构造有向图\n");CreateGraph(G,DG); // 采用数组邻接矩阵表示法,构造有向图break;case 1:printf("构造有向网\n");CreateGraph(G,DN); // 采用数组邻接矩阵表示法,构造有向网AGGbreak;case 2:printf("构造无向图\n");CreateGraph(G,AG); // 采用数组邻接矩阵表示法,构造无向图AGGbreak;case 3:printf("构造无向网\n");CreateGraph(G,AN); // 采用数组邻接矩阵表示法,构造无向网AGGbreak;}PrintMGraph(G); //打印图的邻接矩阵bool*visited=new bool[G.vexnum];int i;cout<<"按图的邻接矩阵得到的深度优先遍历序列"<<endl;for(i=0;i<G.vexnum;i++) visited[i]=false;DFSMatrix(G,0,G.vexnum,visited);cout<<"按图的邻接矩阵得到的广度优先遍历序列"<<endl;for(i=0;i<G.vexnum;i++) visited[i]=false;BFSMatrix(G,0,G.vexnum,visited);cout<<"度:"<<endl;countdig(G);}258://p-258 图的存储结构以邻接表表示, 构造图的算法。

实验九:图的基本操作

实验九:图的基本操作

cout<<q.table[i]<<" "; i=(i+1) % q.size; } cout<<endl; return out; } struct EdgeNode1 // 带权值的边 { int init; // 边的起点 int end; // 边的终点 int weight; // 边的权值 }; class Graph1 //邻接矩阵图类 { private: int visited[MaxSize]; // 访问标记数组 void unvisited(); // 设置未访问标记 void depthfs(int k); // 从结点 k 开始的深度优先遍历 void breadthfs(int k); // 从结点 k 开始的广度优先遍历 public: char vertex[MaxSize]; // 图的结点集,MaxSize 为最大结点数 int mat[MaxSize][MaxSize]; //图的邻接矩阵 int vertCount; // 图的结点数 int edgeCount; // 图的边数 Graph1(); //初始化图的结点集和邻接矩阵 ~Graph1(){} // 析构函数为空 void createGraph(int n,char vert[],int m,EdgeNode1 edge[]); friend ostream& operator<<(ostream& out,Graph1 &g1); void depthFirstSearch(); //图的深度优先遍历 void breadthFirstSearch(); //图的广度优先遍历 void insertVertex(char vert); // 插入结点 void insertEdge(EdgeNode1 e); // 插入边 void insertEdge(int init,int end,int w); void removeVertex(char vert); // 删除结点 void removeEdge(EdgeNode1 e); // 删除边 void removeEdge(int init,int end); //删除边 }; Graph1::Graph1() // 初始化图的结点集和邻接矩阵 { int i,j; for(i=0;i<MaxSize;i++) // 初始化图的结点集 vertex[i]=' '; for(i=0;i<MaxSize;i++) // 初始化图的邻接矩阵 for(j=0;j<MaxSize;j++) if(i==j) mat[i][j]=0; //数据元素权值为 0 else mat[i][j]=MaxWeight; //权值为无穷大 vertCount=0; // 当前结点数为 0 edgeCount=0; // 当前边数为 0 } void Graph1::createGraph(int n,char vert[],int m,EdgeNode1 edge[]) { // 以结点集和边集构造一个图 vertCount=n; // 图的结点个数 int i,j,k; for(i=0;i<n;i++) // 初始结点加入结点集 vertex[i]=vert[i]; edgeCount=m; // 图的边数

实验六 图及其应用

实验六 图及其应用

实验六图及其应用数据结构实验六图及其应用1、实验目的? 熟练掌握图的两种存储结构(邻接矩阵和邻接表)的表示方法 ? 掌握图的基本运算及应用? 加深对图的理解,逐步培养解决实际问题的编程能力2、实验内容:采用邻接表或邻接矩阵方式存储图,实现图的深度遍历和广度遍历;用广度优先搜索方法找出从一顶点到另一顶点边数最少的路径。

1.问题描述:利用邻接表存储结构,设计一种图(有向或无向),并能够对其进行如下操作:1) 创建一个可以随机确定结点数和弧(有向或无向)数的图; 2) 根据图结点的序号,得到该结点的值;3) 根据图结点的位置的第一个邻接顶点的序号,以及下一个邻接顶点的序号;4) 实现从第v 个顶点出发对图进行深度优先递归遍历; 5) 实现对图作深度优先遍历;6) 实现对图进行广度优先非递归遍历; 编写主程序,实现对各不同的算法调用。

2.实现要求:(以邻接表存储形式为例)编写图的基本操作函数::对图的各项操作一定要编写成为C(C++)语言函数,组合成模块化的形式,每个算法的实现要从时间复杂度和空间复杂度上进行评价。

1)“建立图的邻接表算法”:CreateGraph(ALGraph *G) 操作结果:采用邻接表存储结构,构造没有相关信息的图G2)“邻接表表示的图的递归深度优先遍历算法”:DFSTraverse(ALGraphG,void(*Visit)(char*)) 初始条件:图G 已经存在;操作结果:返回图的按深度遍历的结果。

3)“邻接表表示的图的广度优先遍历算法”: BFSTraverse(ALGraphG,void(*Visit)(char*)) 初始条件:图G 已经存在;操作结果:返回图的按广度遍历的结果。

4)“邻接表从某个结点开始的广度优先遍历算法”:BFS(ALGraph G, int v)初始条件:图G 已经存在;操作结果:返回图从某个结点开始的按广度遍历的结果。

分析: 修改输入数据,预期输出并验证输出的结果,加深对有关算法的理解。

数据结构实验队列的基本操作

数据结构实验队列的基本操作

数据结构实验队列的基本操作《数据结构》是计算机相关专业的一门核心基础课程,也是很多高校研究生入学考试专业课必考课程之一。

它主要介绍线性结构、树型结构、图形结构三种逻辑结构元素的存储实现,在此基础上介绍一些典型算法及时、空效率分析。

这门课程的主要任务是培养学生的算法分析、设计能力及良好的程序设计习惯。

通过学习,要求学生能够掌握典型算法的设计思想及程序实现,能够根据实际问题选取合适的存储方案,设计出简洁、高效、实用的算法,为后续课程的学习及软件开发打下良好的基础。

学习这门课程,习题和实验是两个关键环节。

学生理解算法的最佳途径是上机实验。

因此,实验环节的好坏是学生能否学好《数据结构》的关键。

为了更好地配合学生实验,特编写该实验指导书。

一、实验目的、要求和任务计算机编程中加工处理的对象是数据,而数据具有一定的组织结构,所以学习编写计算机程序仅仅了解计算机语言是不够的,还必须掌握数据组织、存储和运算的一般方法,这是数据结构课程中学习和研究的内容。

由于数据结构的原理和算法较抽象,而该课程一般在本科低年级开设,对于计算机程序设计知识的初学者,理解和掌握其中的原理就显得较为困难。

1.熟练掌握C语言的编辑、编译、调试程序。

2.会书写类C语言的算法,并将算法转变为程序实现。

3.正确理解各种数据结构的逻辑特性和存储表示和基本操作的算法实现。

4.有较强的逻辑分析能力。

5.针对问题的不同选择合适的数据结构,提高算法设计的能力和动手实验的技能。

6.学会分析研究计算机加工的数据结构的特性,以便为应用设计的数据选择适当的逻辑结构、存储结构及其相应的算法,并初步掌握算法的时间分析和空间分析的技术。

7.本课程的学习过程也是复杂程序设计的训练过程,要求学生编写的程序结构清楚、正确易读,符合软件过程的规范,从而培养学生的数据抽象能力。

8.通过若干数据结构应用实例,引导学生学习数据类型的使用,为今后学习面向对象的程序做一些铺垫。

二、实验基本内容及学时分配为了达到实验目的,本课程安排了4个实验单元,训练的重点在于基本的数据结构,而不是强调面面俱到。

数据结构实验六 图结构及其应用

数据结构实验六 图结构及其应用

实验七图结构及其应用一、实验目的1.掌握图类的邻接矩阵存储结构的实现;2.掌握图的基本操作,包括图的建立、广度优先遍历和深度优先遍历算法;3.掌握求最短路径的Dijkastra算法。

二、实验要求1.复习课本中第7章关于图的相关知识内容;2.用C++语言完成算法和程序设计并且调试通过;三、实验题目与要求1.图的遍历详细描述:利用以提供的源程序素材,实现对不多于30个结点的图的建立以及广度优先和深度优先遍历算法。

具体功能要求:从键盘中输入网中顶点的个数,以及顶点的数据值,并以顶点的输入次序作为顶点的编号输入顶点与顶点之间的邻接边的权值(注:若为无向图,则每条边可由两条方向相反的有向边构成);若无边相连则已设定的权值最大值MaxWeight=1000代替。

利用顶点与边的信息建立网的邻接矩阵,并第一个输入的顶点为原点对网进行深度优先和广度优先遍历,并输入遍历的顶点序列。

例:如下图7-1图所示,则输入为:6ABCDEF18A B 34A E 12B A 34B C 46B F 19C B 46C D 17C F 25D C 17D E 38D F 25E A 12E D 38E F 26F B 19F D 25F C 25F E 26图7-1 网的图示表示在提供的程序模板中,完成以下函数,实现上述功能;(1)DFSTraverse (MGraph G)功能描述:对网进行深度优先遍历,网可以非连通(2)BFSTraverse (MGraph G)功能描述:对网进行广度优先遍历,网可以非连通2.最短路径求解详细描述:在第一题的基础上,Dijkastra算法求解从第A个顶点到其余各个顶点的最短路径的所经过的顶点以及路径的长度。

例:如图7-1所示,则该求出顶点A到其余个顶点的最短路径所经过的顶点,以及路径的长度;输出如下所示:A->B: A B 34A->C: A E F C 63A->D: A E D 50A->E: A E 12A->F: A E F 38在提供的程序模板中,完成以下函数,实现上述功能;void dijkstra(MGraph G, int vs )3.验证练习先对下图7-2和7-3进行深度和广度优先遍历,并求出以A作为源点求最短路径的结果。

数据结构实验六图结构及其应用

数据结构实验六图结构及其应用

实验七图结构及其应用一、实验目的1.掌握图类的邻接矩阵存储结构的实现;2.掌握图的基本操作,包括图的建立、广度优先遍历和深度优先遍历算法;3.掌握求最短路径的Dijkastra算法。

二、实验要求1.复习课本中第7章关于图的相关知识内容;2.用C+叫言完成算法和程序设计并且调试通过;三、实验题目与要求1.图的遍历详细描述:利用以提供的源程序素材,实现对不多于30个结点的图的建立以及广度优先和深度优先遍历算法。

具体功能要求:从键盘中输入网中顶点的个数,以及顶点的数据值,并以顶点的输入次序作为顶点的编号输入顶点与顶点之间的邻接边的权值(注:若为无向图,则每条边可由两条方向相反的有向边构成);若无边相连则已设定的权值最大值MaxWeight=100O弋替。

利用顶点与边的信息建立网的邻接矩阵,并第一个输入的顶点为原点对网进行深度优先和广度优先遍历,并输入遍历的顶点序列。

例:如下图7-1图所示,则输入为:6ABCDEF18A B 34A E 12B A 34B C 46B F 19C B 46C D 17C F 25D C 17D E 38D F 25E A 12E D 38E F 26F B 19F D 25F C 25F E 26在提供的程序模板中,完成以下函数,实现上述功能;(1)DFSTraverse (MGraph G)功能描述:对网进行深度优先遍历,网可以非连通(2)BFSTraverse (MGraph G)功能描述:对网进行广度优先遍历,网可以非连通2.最短路径求解详细描述:在第一题的基础上,Dijkastra算法求解从第A个顶点到其余各个顶点的最短路径的所经过的顶点以及路径的长度。

例:如图7-1所示,则该求出顶点A0其余个顶点的最短路径所经过的顶点,以及路径的长度;输出如下所示:A->B: A B 34A->C: A E F C 63A->D: A E D 50A->E: A E 12A->F: A E F 38在提供的程序模板中,完成以下函数,实现上述功能;void dijkstra(MGraph G, int vs )3.验证练习先对下图7-2和7-3进行深度和广度优先遍历,并求出以A作为源点求最短路径的结果。

数据结构——图的基本操作

数据结构——图的基本操作

1.实验题目图的基本操作2.实验目的1)掌握图的邻接矩阵、邻接表的表示方法。

2)掌握建立图的邻接矩阵的算法。

3)掌握建立图的邻接表的算法。

4)加深对图的理解,逐步培养解决实际问题的编程能力3.需求分析(1)编写图基本操作函数。

①建立图的邻接表,邻接矩阵Create_Graph( LGraph lg. MGraph mg )②邻接表表示的图的递归深度优先遍历LDFS( LGraph g, int i )③邻接矩阵表示的图的递归深度优先遍历MDFS( MGraph g,int i, int vn )④邻接表表示的图的广度优先遍历LBFS( LGraph g, int s, int n )⑤邻接矩阵表示的图的广度优先遍历MBFS(MGraph g, int s, int n )(2)调用上述函数实现下列操作。

①建立一个图的邻接矩阵和图的邻接表。

②采用递归深度优先遍历输出图的邻接矩阵③采用递归深度优先遍历输出图的邻接表。

④采用图的广度优先调历输出图的邻接表。

⑤采用图的广度优先遍历输出图的邻接矩阵4.概要设计(1):/**********************************图的基本操作**********************************/ //------------------------------- 邻接矩阵数据类型的定义--------------------------------// 最大顶点个数typedef struct{char vexs[MAX_VERTEX_NUM]; // 顶点向量int acrs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 邻接矩阵int vexnum,arcnum; // 图当前顶点数和弧数}MGraph ;//--------------------------------邻接表数据类型的定义----------------------------------typedef struct ArcNode{福建师范大学物光院计算机教学辅导讲义struct ArcNode *nextarc;// 指向下一条弧的指针}ArcNode;typedef struct VNode { char data;// 顶点信息ArcNode *firstarc;// 指向第一条依附该顶点的弧的指针}VNode, AdjList[MAX_VERTEX_NUM]; typedef struct { AdjList vertices;int vexnum,arcnum;// 图当前顶点数和弧数}LGraph;(2) 本程序主要包含6个函数:• 主函数 main()• 建立图的邻接矩阵,邻接表Create_Graph () • 邻接表表示的图的递归深度优先遍历 LDFS () • 邻接矩阵表示的图的递归深度优先遍历 MDFS () • 邻接表表示的图的广度优先遍历 LBFS () • 邻接矩阵表示的图的广度优先遍历MBFS ()各函数间调用关系如下:(3) 主函数的伪码main(){ 定义邻接矩阵和邻接表;建立邻接矩阵和邻接表; 邻接矩阵MDFS 深度优先遍历; 邻接矩阵MBFS 广度优先遍历 ; 邻接表LDFS 深度优先遍历; 邻接表LBFS 广度优先遍历mainCreate_Graph () LDFS () MDFS ()LBFS () MBFS ()5详细设计/**********************************图的基本操作**********************************/ //------------------------------- 邻接矩阵数据类型的定义--------------------------------// 最大顶点个数typedef struct{char vexs[MAX_VERTEX_NUM]; // 顶点向量int acrs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 邻接矩阵int vexnum,arcnum; // 图当前顶点数和弧数}MGraph ;//--------------------------------邻接表数据类型的定义----------------------------------typedef struct ArcNode{int adjvex; // 该弧所指向的顶点的位置struct ArcNode *nextarc; // 指向下一条弧的指针}ArcNode;typedef struct VNode{char data; // 顶点信息ArcNode *firstarc; // 指向第一条依附该顶点的弧的指针}VNode, AdjList[MAX_VERTEX_NUM];typedef struct{AdjList vertices;int vexnum,arcnum; // 图当前顶点数和弧数}LGraph;int Create_Graph( MGraph *Mg , LGraph *Lg ) // 建立图的邻接矩阵,邻接表{输入图的顶点个数(字符),构造顶点向量输入图的任意两个顶点的弧构造邻接矩阵构造邻接表}void LDFS(LGraph *Lg,int i) 邻接表表示的图的递归深度优先遍历{显示顶点向量,指针指向下一个顶点向量下一个顶点没有被访问,继续否则退会上一个顶点向量的另一个边}void MDFS(MGraph *Mg,int i) 邻接矩阵表示的图的递归深度优先遍历显示顶点向量,指针指向下一个顶点向量下一个顶点没有被访问,继续否则退会上一个顶点向量的另一个边}void LBFS( LGraph *Lg )邻接表表示的图的广度优先遍历{初始化visited[]初始化队列没被访问过显示顶点向量入队出队访问下一个顶点向量}void MBFS(MGraph *Mg )邻接矩阵表示的图的广度优先遍历{初始化visited[]初始化队列没被访问过显示顶点向量入队出队访问下一个顶点向量}//-------------------主函数-------------------------------main(){ 定义邻接矩阵和邻接表;建立邻接矩阵和邻接表;邻接矩阵MDFS深度优先遍历;邻接矩阵MBFS广度优先遍历;邻接表LDFS深度优先遍历;邻接表LBFS广度优先遍历}6测试结果7. 参考文献《数据结构》8.附录#include <stdio.h>#include <malloc.h>#include <stddef.h>#include <math.h>#define OK 1#define ERROR 0#define MAX_VERTEX_NUM 20/**********************************图的基本操作**********************************/ int visited[MAX_VERTEX_NUM]; // 访问标志数组//------------------------------- 邻接矩阵数据类型的定义--------------------------------// 最大顶点个数typedef struct{char vexs[MAX_VERTEX_NUM]; // 顶点向量int acrs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 邻接矩阵int vexnum,arcnum; // 图当前顶点数和弧数}MGraph ;//--------------------------------邻接表数据类型的定义----------------------------------typedef struct ArcNode{int adjvex; // 该弧所指向的顶点的位置struct ArcNode *nextarc; // 指向下一条弧的指针}ArcNode;typedef struct VNode{char data; // 顶点信息ArcNode *firstarc; // 指向第一条依附该顶点的弧的指针}VNode, AdjList[MAX_VERTEX_NUM];typedef struct{AdjList vertices;int vexnum,arcnum; // 图当前顶点数和弧数}LGraph;//_________________________________队列函数__________________________________________ typedef struct Queue{int arry[MAX_VERTEX_NUM];int front,rear;}Queue;Queue Q;void InitQueue() // 队列初始化{Q.front=Q.rear=0;}int QueueEmpty(Queue *Q) // 清空队列{if(Q->front==Q->rear)return 1;elsereturn 0;}void EnQueue(Queue *Q,int w)// 入队{if((Q->rear+1)%MAX_VERTEX_NUM==Q->front)printf("Error!");else{Q->arry[Q->rear]=w;Q->rear=(Q->rear+1)%MAX_VERTEX_NUM;}}int DeQueue(Queue *Q) // 出队{int u;if(Q->front==Q->rear)return -1;u=Q->front;Q->front=(Q->front+1)%MAX_VERTEX_NUM;return u;}//____________________________________队列函数end_______________________________________ /**************************************************************************************** *函数:Create_Graph*功能:建立图的邻接矩阵,邻接表*说明:该构建的为无向网mg 为邻接矩阵,lg为邻接表, 无权值***************************************************************************************/ int Locatevex(MGraph *Mg , char v) // 确定v 元素在Mg中的位置{int i;for(i=0;Mg->vexs[i]!=v;i++);if(i>Mg->vexnum) // 输入的元素不正确则显示错误printf("ERROR ");return i; // 返回位置}int Create_Graph( MGraph *Mg , LGraph *Lg ) // 建立图的邻接矩阵,邻接表{int i , j , k ;char v1 , v2 ;ArcNode *q,*p;printf("输入图的顶点数和弧数: ");scanf("%d %d",&Mg->vexnum,&Mg->arcnum);getchar();Lg->vexnum=Mg->vexnum; // 邻接表的顶点数和弧数Lg->arcnum=Mg->arcnum;for(i=0;i<Mg->vexnum;i++) // 构造顶点向量{printf("请输入一个图的顶点(字符):");scanf("%c" , &Mg->vexs[i]);getchar();Lg->vertices[i].data=Mg->vexs[i]; // 赋值Lg->vertices[i].firstarc=NULL; // 指向第一条依附该顶点的弧的指针为空}for(i=0;i<Mg->vexnum;i++) // 初始化邻接矩阵for(j=0;j<Mg->vexnum;j++)Mg->acrs[i][j]=0 ;for(k=0;k<Mg->arcnum;k++) // 构造邻接矩阵和邻接表{printf("请输入一条边连接的2个顶点:");scanf("%c %c",&v1,&v2);getchar();i=Locatevex(Mg,v1); // 确定v1 在Mg 中的位置j=Locatevex(Mg,v2); // 确定v2 在Mg 中的位置Mg->acrs[j][i]=Mg->acrs[i][j]=1; // 置《v1,v2》的对称弧《v2,v1》p=(ArcNode *)malloc(sizeof(ArcNode));p->adjvex=i; // 确认顶点位置p->nextarc=Lg->vertices[j].firstarc;// 指向下一条弧的指针Lg->vertices[j].firstarc=p; // 赋值q=(ArcNode *)malloc(sizeof(ArcNode));q->adjvex=j; // 确认顶点位置q->nextarc=Lg->vertices[i].firstarc;// 指向下一条弧的指针Lg->vertices[i].firstarc=q; // 赋值}return OK ;}/**************************************************************************************** *函数:LDFS*功能:邻接表表示的图的递归深度优先遍历*说明:***************************************************************************************/ int LAdjVex(LGraph *Lg,int k) // 位置{ArcNode *p;for(p=Lg->vertices[k].firstarc;p!=NULL;p=p->nextarc)if(!visited[p->adjvex])return p->adjvex;return -1;}void LDFS(LGraph *Lg,int i){int k;visited[i]=OK;printf("%c",Lg->vertices[i].data);for(k=LAdjVex(Lg,i);k>=0;k=LAdjVex(Lg,k))if(!visited[k])LDFS(Lg,k);}/**************************************************************************************** *函数:MDFS*功能:邻接矩阵表示的图的递归深度优先遍历*说明:***************************************************************************************/ int AdjVes(MGraph *Mg,int k) // 位置{int i;for(i=0;i<Mg->vexnum;i++)if(Mg->acrs[k][i]&&(!visited[i]))return i;return -1;}void MDFS(MGraph *Mg,int i) // 递归深度优先遍历{int k;visited[i]=1; // 访问标志数组某位置1printf("%c",Mg->vexs[i]); // 显示for(k=AdjVes(Mg,i);k>=0;k=AdjVes(Mg,k))if(!visited[k])MDFS(Mg,k); // 递归}/**************************************************************************************** *函数:LBFS*功能:邻接表表示的图的广度优先遍历*说明:***************************************************************************************/void LBFS( LGraph *Lg ){int i,u,w;for(i=0;i<Lg->vexnum;++i) // 初始化visited[]visited[i]=0;InitQueue(); // 初始化队列for(i=0;i<Lg->vexnum;++i)if(!visited[i]) // 没被访问过{visited[i]=1;printf("%c",Lg->vertices[i].data);EnQueue(&Q,i); // 入队while(!QueueEmpty(&Q)){u=DeQueue(&Q); // 出队for(w=LAdjVex(Lg,u);w>=0;w=LAdjVex(Lg,u))if(!visited[w]) // 没被访问过{visited[w]=1;printf("%c",Lg->vertices[w].data);EnQueue(&Q,w); // 入队}}}}/**************************************************************************************** *函数:MBFS*功能:邻接矩阵表示的图的广度优先遍历*说明:***************************************************************************************/ void MBFS(MGraph *Mg ){int i,w,u;for(i=0;i<Mg->vexnum;i++) // 初始化visited[]visited[i]=0;InitQueue(); // 初始化队列for(i=0;i<Mg->vexnum;++i)if(!visited[i]) // 没被访问过{visited[i]=1;printf("%c",Mg->vexs[i]); // 显示EnQueue(&Q,i); // 入队while(!QueueEmpty(&Q)){u=DeQueue(&Q); // 出队for(w=AdjVes(Mg,u);w>=0;w=AdjVes(Mg,u))if(!visited[w]) // 没被访问过{visited[w]=1;printf("%c",Mg->vexs[w]);// 显示EnQueue(&Q,w); // 入队}福建师范大学物光院计算机教学辅导讲义}}}/***************************************主函数*******************************************/void main(){int i ;MGraph Mg;LGraph Lg;Create_Graph( &Mg, &Lg);printf("邻接矩阵MDFS深度优先遍历:\t");for(i=0;i<Mg.vexnum;i++)visited[i]=0; // 初始化visited[]for(i=0;i<Mg.vexnum;i++)if(!visited[i])MDFS(&Mg,i); // 遍历Mgprintf("\n邻接矩阵MBFS广度优先遍历:\t");MBFS(&Mg) ; // 遍历Mgprintf("\n");printf("邻接表LDFS深度优先遍历:\t");for(i=0;i<Lg.vexnum;++i)visited[i]=0; // 初始化visited[]for(i=0;i<Lg.vexnum;++i)if(!visited[i])LDFS(&Lg,i); // 遍历Lgprintf("\n邻接表LBFS广度优先遍历:\t");LBFS(&Lg) ; // 遍历Lgprintf("\n");}}注意事项:●每位同学必须完成实验任务,并提交实验报告。

实验六 图及图的操作

实验六 图及图的操作

实验报告六图及图的操作实验一、实验目的:1、掌握图的基本概念和术语2、掌握图的存储结构及创建算法。

3、掌握图的遍历算法(递归或非递归算法)。

二、实验内容:1、图邻接矩阵存储结构表示及基本操作算法实现(1)邻接矩阵存储结构类定义:自定义如下:public interface LList<T> {boolean isEmpty();int length();T get(int i);void set(int i,T x);void insert(int i,T x);void append(T x);T remove(int i);void removeAll();}public class SeqList<T> implements LList<T> {private Object[] element;private int len;public SeqList(int size){this.element=new Object[size];this.len = 0;}public SeqList(SeqList<T> list){this(list.len);this.len=list.len;}public SeqList(){this(64);}public boolean isEmpty(){return this.len==0;}public int length(){return this.len;}public T get(int i){if(i>=0&&i<this.len)return (T)this.element[i];return null;}public void set(int i, T x){if(x==null)return;if(i>=0&&i<this.len)this.element[i] = x;elsethrow new IndexOutOfBoundsException(i+""); }public String toString(){String str = "(";if(this.len>0)str += this.element[0].toString();for(int i=1;i<this.len;i++)str +=","+this.element[i].toString();return str+")";}public void insert(int i, T x){if(x==null)return;if(this.len==element.length){Object[] temp = this.element;this.element=new Object[temp.length*2];for(int j=0;j < temp.length;i++)this.element[j]=temp[j];}if(i<0)i=0;if(i>this.len)i=this.len;for(int j=this.len-1;j>=i;j--)this.element[j+1] = this.element[j];this.element[i]=x;this.len++;}public void append(T x){insert(this.len,x);}public T remove(int i){if(this.len==0||i<0||i>=len)return null;T old = (T)this.element[i];for(int j=0;j<this.len-1;j++)this.element[j] = this.element[j+1];this.element[this.len-1]=null;this.len--;return old;}public void removeAll(){this.len=0;}}(2)创建邻接矩阵算法创建无向图邻接矩阵算法:public class MatrixGraph<T> {protected SeqList<T> vertexlist;protected int[][] adjmatrix;private final int Max=0;public MatrixGraph(int size){size=size<10?10:size;this.vertexlist=new SeqList<T>(size);this.adjmatrix=new int[size][size];for(int i=0;i<size;i++)for(int j=0;j<size;j++)this.adjmatrix[i][j]=(i==j)?0:Max;}public MatrixGraph(T[] vertices,Edge[] edges){ this(vertices.length);if(vertices==null)return;for(int i=0;i<vertices.length;i++)insertVertex(vertices[i]);if(edges!=null)for(int j=0;j<edges.length;j++)insertEdge(edges[j]);}public int vertexCount(){return this.vertexlist.length();}public T get(int i){return this.vertexlist.get(i);}public int getWeight(int i,int j){return this.adjmatrix[i][j];}public String toString(){String str="顶点集合:"+this.vertexlist.toString()+"\n 邻接矩阵:\n";int n=this.vertexCount();for(int i=0;i<n;i++){for(int j=0;j<n;j++)str+=this.adjmatrix[i][j]==Max?" 0":" "+this.adjmatrix[i][j];str+="\n";}return str;}public int insertVertex(T x){this.vertexlist.append(x);if(this.vertexCount()>this.adjmatrix.length){int temp[][]=adjmatrix,i,j;this.adjmatrix=new int[temp.length*2][temp.length^2];for(i=0;i<temp.length;i++){for(j=0;j<temp.length;j++)this.adjmatrix[i][j]=temp[i][j];for(j=temp.length;j<temp.length*2;i++)this.adjmatrix[i][j]=Max;}for(i=temp.length;i<temp.length*2;i++)for(j=0;j<temp.length*2;j++)this.adjmatrix[i][j]=(i==j)?0:Max;}return this.vertexlist.length()-1;}public void insertEdge(int i,int j,int weight){int n=this.vertexCount();if(i>=0&&i<n&&j>=0&&i!=j&&this.adjmatrix[i][j]==Max) this.adjmatrix[i][j]=weight;}public void insertEdge(Edge edge){this.insertEdge(edge.start,edge.dest,edge.weight);}}创建无向网邻接矩阵算法:public class MatrixGraph<T> {protected SeqList<T> vertexlist;protected int[][] adjmatrix;private final int Max=99999;public MatrixGraph(int size){size=size<10?10:size;this.vertexlist=new SeqList<T>(size);this.adjmatrix=new int[size][size];for(int i=0;i<size;i++)for(int j=0;j<size;j++)this.adjmatrix[i][j]=(i==j)?0:Max;}public MatrixGraph(T[] vertices,Edge[] edges){this(vertices.length);if(vertices==null)return;for(int i=0;i<vertices.length;i++)insertVertex(vertices[i]);if(edges!=null)for(int j=0;j<edges.length;j++)insertEdge(edges[j]);}public int vertexCount(){return this.vertexlist.length();public T get(int i){return this.vertexlist.get(i);}public int getWeight(int i,int j){return this.adjmatrix[i][j];}public String toString(){String str="顶点集合:"+this.vertexlist.toString()+"\n 邻接矩阵:\n";int n=this.vertexCount();for(int i=0;i<n;i++){for(int j=0;j<n;j++)str+=this.adjmatrix[i][j]==Max?" ∞":" "+this.adjmatrix[i][j];str+="\n";}return str;}public int insertVertex(T x){this.vertexlist.append(x);if(this.vertexCount()>this.adjmatrix.length){int temp[][]=adjmatrix,i,j;this.adjmatrix=new int[temp.length*2][temp.length^2];for(i=0;i<temp.length;i++){for(j=0;j<temp.length;j++)this.adjmatrix[i][j]=temp[i][j];for(j=temp.length;j<temp.length*2;i++)this.adjmatrix[i][j]=Max;}for(i=temp.length;i<temp.length*2;i++)for(j=0;j<temp.length*2;j++)this.adjmatrix[i][j]=(i==j)?0:Max;}return this.vertexlist.length()-1;}public void insertEdge(int i,int j,int weight){int n=this.vertexCount();if(i>=0&&i<n&&j>=0&&i!=j&&this.adjmatrix[i][j]==Max)this.adjmatrix[i][j]=weight;}public void insertEdge(Edge edge){this.insertEdge(edge.start,edge.dest,edge.weight);}}创建有向图邻接矩阵算法:(可使用前无向图邻接矩阵算法)创建有向网邻接矩阵算法:(可使用前无向图邻接矩阵算法)(3)输出邻接矩阵结果算法public static void main(String[] args){String[] vertices={"A","B","C","D","E"};Edge edges[]={new Edge(0,1,1),new Edge(0,3,1),new Edge(1,0,1),new Edge(1,2,1),new Edge(1,3,1),new Edge(2,1,1),new Edge(2,3,1),new Edge(2,4,1),new Edge(3,0,1),new Edge(3,1,1),new Edge(3,2,1),new Edge(3,4,1),new Edge(4,2,1),new Edge(4,3,1),};MatrixGraph<String> graph=new MatrixGraph<String>(vertices,edges);System.out.println("无向图:"+graph.toString());}public static void main(String[] args){String[] vertices={"A","B","C","D","E"};Edge edges[]={new Edge(0,1,5),new Edge(0,3,2),new Edge(1,0,5),new Edge(1,2,7),new Edge(1,3,6),new Edge(2,1,7),new Edge(2,3,8),new Edge(2,4,3),new Edge(3,0,2),new Edge(3,1,6),new Edge(3,2,8),new Edge(3,4,9),new Edge(4,2,3),new Edge(4,3,9)};MatrixGraph<String> graph=new MatrixGraph<String>(vertices,edges);System.out.println("无向网:"+graph.toString());}public static void main(String[] args){String[] vertices={"A","B","C","D","E"};Edge edges[]={new Edge(0,1,1),new Edge(0,3,1),new Edge(1,3,1),new Edge(2,3,1),new Edge(2,4,1),new Edge(3,1,1),new Edge(3,2,1),new Edge(4,2,1),new Edge(4,3,1)};MatrixGraph<String> graph=new MatrixGraph<String>(vertices,edges);System.out.println("有向图:"+graph.toString());}public static void main(String[] args){String[] vertices={"A","B","C","D","E"};Edge edges[]={new Edge(0,1,5),new Edge(0,3,2),new Edge(1,3,6),new Edge(2,3,8),new Edge(2,4,3),new Edge(3,1,9),new Edge(3,2,2),new Edge(4,2,3),new Edge(4,3,9)};MatrixGraph<String> graph=new MatrixGraph<String>(vertices,edges);System.out.println("有向网:"+graph.toString());}测试结果粘贴如下:2、图邻接表存储结构表示及基本操作算法实现(1)邻接表存储结构类定义:自定义如下:public class Vertex<T> {public T data;public SortedSinglyLinkedList<Edge> adjlink;public Vertex(T data){this.data=data;this.adjlink=new SortedSinglyLinkedList<Edge>();}public String toString(){return"\n"+this.data.toString()+": "+this.adjlink.toString();}}(2)创建邻接表算法创建无向网邻接表算法:(可使用下有向网邻接表算法)创建有向网邻接表算法:public class AdjListGraph<T> {protected SeqList<Vertex<T>> vertexlist;public AdjListGraph(int size){size=size<10?10:size;this.vertexlist=new SeqList<Vertex<T>>(size);}public AdjListGraph(T[] vertices,Edge[] edges){this(vertices.length*2);if(vertices==null)return;for(int i=0;i<vertices.length;i++)insertVertex(vertices[i]);if(edges!=null)for(int j=0;j<edges.length;j++)insertEdge(edges[j]);}public String toString(){return"出边表: \n"+this.vertexlist.toString()+"\n";}public int insertVertex(T x){this.vertexlist.append(new Vertex<T>(x));return this.vertexlist.length()-1;}public int vertexCount(){return this.vertexlist.length();}public void insertEdge(int i,int j,int weight){if(i>=0&&i<vertexCount()&&j>=0&&j<vertexCount()&&i!=j){Edge edge=new Edge(i,j,weight);SortedSinglyLinkedList<Edge>adjlink=this.vertexlist.get(i).adjlink;Node<Edge> front=adjlink.head,p=front.next;while(p!=null&&pareTo(edge)<0){front=p;p=p.next;}if(p!=null&&pareTo(edge)==0)return;front.next=new Node<Edge>(edge,p);}}public void insertEdge(Edge edge){this.insertEdge(edge.start,edge.dest,edge.weight);}(3)输出邻接表结果算法public static void main(String[] args){String[] vertices={"A","B","C","D","E"};Edge edges[]={new Edge(0,1,5),new Edge(0,3,2),new Edge(1,0,5),new Edge(3,0,2),new Edge(2,4,3),new Edge(4,2,3)};AdjListGraph<String> graph=new AdjListGraph<String>(vertices,edges);System.out.println("无向网:"+graph.toString());}public static void main(String[] args){String[] vertices={"A","B","C","D","E"};Edge edges[]={new Edge(0,1,5),new Edge(0,3,2),new Edge(1,0,6),new Edge(1,2,7),new Edge(2,4,3),new Edge(3,2,8),new Edge(3,4,9)};AdjListGraph<String> graph=new AdjListGraph<String>(vertices,edges);System.out.println("有向网:"+graph.toString());}测试结果粘贴如下:3、图的遍历递归算法(1)(存储结构为邻接表)深度优先遍历算法递归算法:public interface QQueue<T> {boolean isEmply();void enqueue(T x);T dequeue();}public class SeqQueue<T> implements QQueue<T>{private Object element[];private int front,rear;public SeqQueue(int length){if(length<64)length=64;this.element=new Object[Math.abs(length)];this.front=this.rear=0;}public SeqQueue(){this(64);}public boolean isEmply(){return this.front==this.rear;}public void enqueue(T x){if(x==null)return;if(this.front==(this.rear+1)%this.element.length){ Object[] temp = this.element;this.element=new Object[temp.length*2];int i=this.front,j=0;while(i!=this.rear){this.element[j]=temp[i];i=(i+1)%temp.length;j++;}this.front=0;this.rear=j;}this.element[this.rear]=x;this.rear=(this.rear+1)%this.element.length;}public T dequeue(){if(isEmply())return null;T temp=(T)this.element[this.front];this.front=(this.front+1)%this.element.length;return temp;}public String toString(){String str="(";if(!isEmply()){str+=this.element[this.front].toString();int i=(this.front+1)%this.element.length;while(i!=this.rear){str+=","+this.element[i].toString();i=(i+1)%this.element.length;}}return str+=")";}public int length(){return(this.element.length+this.rear-this.front)%(this.element.length);}}public abstract class AbstractGraph<T> {public abstract int vertexCount();public abstract T get(int i);public abstract int getNextNeighbor(int i,int j);public void DFSTraverse(int i){boolean[] visited= new boolean[this.vertexCount()];int j=i;do{if(!visited[j]){System.out.print("{");this.depthfs(j,visited);System.out.print("}");}j=(j+1)%this.vertexCount();}while(j!=i);System.out.println();}public void depthfs(int i,boolean[] visited){System.out.print(this.get(i)+" ");visited[i]=true;int j=this.getNextNeighbor(i, -1);while(j!=-1){if(!visited[j])depthfs(j,visited);j=this.getNextNeighbor(i, j);}}}public class AdjListGraph<T> extends AbstractGraph<T>{ protected SeqList<Vertex<T>> vertexlist;public AdjListGraph(int size){size=size<10?10:size;this.vertexlist=new SeqList<Vertex<T>>(size);}public T get(int i){return this.vertexlist.get(i).data;}public AdjListGraph(T[] vertices,Edge[] edges){this(vertices.length*2);if(vertices==null)return;for(int i=0;i<vertices.length;i++)insertVertex(vertices[i]);if(edges!=null)for(int j=0;j<edges.length;j++)insertEdge(edges[j]);}public String toString(){return"出边表: \n"+this.vertexlist.toString()+"\n";}public int insertVertex(T x){this.vertexlist.append(new Vertex<T>(x));return this.vertexlist.length()-1;}public int vertexCount(){return this.vertexlist.length();}public void insertEdge(int i,int j,int weight){if(i>=0&&i<vertexCount()&&j>=0&&j<vertexCount()&&i!=j){ Edge edge=new Edge(i,j,weight);SortedSinglyLinkedList<Edge>adjlink=this.vertexlist.get(i).adjlink;Node<Edge> front=adjlink.head,p=front.next;while(p!=null&&pareTo(edge)<0){front=p;p=p.next;}if(p!=null&&pareTo(edge)==0)return;front.next=new Node<Edge>(edge,p);}}public void insertEdge(Edge edge){this.insertEdge(edge.start,edge.dest,edge.weight);}public int getNextNeighbor(int i,int j){int n=this.vertexCount();if(i>=0&&i<n&&j>=-1&&j<n&&i!=j){Node<Edge> p=this.vertexlist.get(i).adjlink.head.next;while(p!=null){if(p.data.dest>j)return p.data.dest;p=p.next;}}return -1;}public static void main(String[] args){String[] vertices={"A","B","C","D","E"};Edge edges[]={new Edge(0,1,1),new Edge(0,3,1),new Edge(1,0,1),new Edge(1,2,1),new Edge(1,3,1),new Edge(3,0,1),new Edge(3,1,1),new Edge(3,2,1),newEdge(3,4,1),new Edge(2,3,1),new Edge(2,1,1),new Edge(2,4,1),new Edge(4,2,1),new Edge(4,3,1)};AdjListGraph<String> graph=new AdjListGraph<String>(vertices,edges);System.out.println(graph.toString());for(int i=0;i<graph.vertexCount();i++){graph.DFSTraverse(i);}}}public static void main(String[] args){String[] vertices={"A","B","C","D","E"};Edge edges[]={new Edge(0,1,1),new Edge(0,3,1),new Edge(1,0,1),new Edge(1,2,1),new Edge(3,2,1),new Edge(3,4,1),new Edge(2,4,1),};AdjListGraph<String> graph=new AdjListGraph<String>(vertices,edges);System.out.println(graph.toString());for(int i=0;i<graph.vertexCount();i++){graph.DFSTraverse(i);}}测试结果粘贴如下:有向网的测试结果:无向网的测试结果:(2)广度优先遍历算法非递归算法public abstract class AbstractGraph<T> {public abstract int vertexCount();public abstract T get(int i);public abstract int getNextNeighbor(int i,int j);public void BFSTraverse(int i){boolean[] visited=new boolean[this.vertexCount()];int j=i;do{if(!visited[j]){System.out.print("{");breadthfs(j,visited);System.out.print("}");}j=(j+1)%this.vertexCount();}while(j!=i);System.out.println();}public void breadthfs(int i,boolean[] visited){System.out.print(this.get(i)+" ");visited[i]=true;SeqQueue<Integer> que=new SeqQueue<Integer>(this.vertexCount());que.enqueue(new Integer(i));while(!que.isEmply()){i=que.dequeue().intValue();int j=this.getNextNeighbor(i, -1);while(j!=-1){if(!visited[j]){System.out.print(this.get(j)+"");visited[j]=true;que.enqueue(new Integer(j));}j=this.getNextNeighbor(i, j);}}}}public static void main(String[] args){String[] vertices={"A","B","C","D","E"};Edge edges[]={new Edge(0,1,1),new Edge(0,3,1),new Edge(1,0,1),new Edge(1,2,1),new Edge(3,2,1),new Edge(3,4,1),new Edge(2,4,1),};AdjListGraph<String> graph=new AdjListGraph<String>(vertices,edges);System.out.println(graph.toString());for(int i=0;i<graph.vertexCount();i++){graph.BFSTraverse(i);}}public static void main(String[] args){String[] vertices={"A","B","C","D","E"};Edge edges[]={new Edge(0,1,1),new Edge(0,3,1),new Edge(1,0,1),new Edge(1,2,1),new Edge(1,3,1),new Edge(3,0,1),new Edge(3,1,1),new Edge(3,2,1),newEdge(3,4,1),new Edge(2,3,1),new Edge(2,1,1),new Edge(2,4,1),new Edge(4,2,1),new Edge(4,3,1)};AdjListGraph<String> graph=new AdjListGraph<String>(vertices,edges);System.out.println(graph.toString());for(int i=0;i<graph.vertexCount();i++){graph.BFSTraverse(i);}}测试结果粘贴如下:有向网的测试结果:无向网的测试结果:三、实验心得(含上机中所遇问题的解决办法,所使用到的编程技巧、创新点及编程的心得)图这一章牵涉很广,仅是上三道题,就需要线性表、单链表、队列三种存储方式。

《数据结构》实验书

《数据结构》实验书

目录实验一线性表基本操作的编程实现 (201)实验二堆栈或队列基本操作的编程实现 (49)实验四二维数组基本操作的编程实现 (18)实验五二叉树基操作的编程实现 (20)实验六图基本操作的编程实现 (45)(特别提示:程序设计包含两个方面的错误。

其一是错误,其二是能错误。

为了提高学生的编程和能力,本指导书给出的程序代码并的两种错误。

并且也不保证程序的完整性,有一些语句已经故意删除,就是要求学生自己编制完成,这样才能达到我们的要求。

希望大家以自己所学高级语言的基本功和点为基础,不要过于依赖给出的参考代码,这样才能有所进步。

如果学生能够根据要求完全自己编制,那就不好了。

)实验一线性表基本操作的编程实现【实验目的】线性表基本操作的编程实现要求:线性表基本操作的编程实现(2学时,验证型),掌握线性表的建立、遍历、插入、删除等基本操作的编程实现,也可以进一步编程实现查找、逆序、排序等操作,存储结构可以在顺序结构或链表结分主要功能,也可以用菜单进行管理完成大部分功能。

还鼓励学生利用基本操作进行一些更实际的应用型程序设计。

【实验性质】【实验内容】把线性表的顺序存储和链表存储的数据插入、删除运算其中某项进行程序实现。

建议实现键盘输入数据以实现程序的通据的函数。

【注意事项】【思考问题】1.线性表的顺序存储和链表存储的差异?优缺点分析?2.那些操作引发了数据的移动?3.算法的时间效率是如何体现的?4.链表的指针是如何后移的?如何加强程序的健壮性?【参考代码】(一)利用顺序表完成一个班级学生课程成绩的简单管理1、预定义以及顺序表结构类型的定义(1)#define ListSize //根据需要自己设定一个班级能够容纳的最大学生数(2)typedef struct Stu{int num; //学生的学号char name[10]; //学生的姓名float wuli; //物理成绩float shuxue; //数学成绩float yingyu; //英语成绩}STUDENT; //存放单个学生信息的结构体类型typedef struct List{stu[ListSize]; //存放学生的数组定义,静态分配空间int length; //记录班级实际学生个数}LIST; //存放班级学生信息的顺序表类型2、建立班级的学生信息void listcreate(LIST *Li,int m) //m为该班级的实际人数{int i;Li->length=0;for(i=0;i<m;i++) //输入m个学生的所有信息{printf("please input the %dth student's information:\n",i+1);printf("num=");scanf("%d", ); //输入第i个学生的学号printf("name=");scanf("%s", ); //输入第i个学生的姓名printf("wuli=");scanf("%f", ); //输入第i个学生的物理成绩printf("shuxue=");scanf("%f", ); //输入第i个学生的数学成绩printf("yingyu=");scanf("%f", ); //输入第i个学生的英语成绩Li->length++; //学生人数加1}}3、插入一个学生信息int listinsert(LIST *Li,int i) //将学生插入到班级Li的第i个位置。

数据结构实验-图的基本操作

数据结构实验-图的基本操作

#include<stdio.h>#include<malloc.h>#define MAXV 30typedef int InfoType;typedef struct{int no;InfoType info;}VertexType;typedef struct{VertexType vexs[MAXV];int arcs[MAXV][MAXV];int vexnum,arcnum;}MGraph;typedef struct ArcNode{int adjvex;int weight;struct ArcNode *nextarc;}ArcNode;typedef struct VNode{VertexType data;ArcNode *firstarc;}VNode;//typedef VNode AdjList[MAXV]; typedef struct{VNode vertices[MAXV];int vexnum,arcnum;}LGraph;int visited[MAXV];int queue[MAXV];void CreateMG(MGraph &mg){int i,j;int A[7][7];mg.vexnum=7;mg.arcnum=9;for(i=0;i<mg.vexnum;i++)for(j=0;j<mg.vexnum;j++)A[i][j]=0;A[0][1]=A[0][2]=A[0][6]=1;A[1][3]=1;A[2][3]=A[2][5]=A[2][6]=1;A[3][4]=1;A[5][6]=1;for(i=1;i<mg.vexnum;i++)for(j=0;j<i;j++)A[i][j]=A[j][i];for(i=0;i<mg.vexnum;i++)for(j=0;j<mg.vexnum;j++)mg.arcs[i][j]=A[i][j];}void CreatLG(LGraph *&lg,MGraph mg){int i,j;ArcNode *p;lg=(LGraph *)malloc(sizeof(LGraph));for(i=0;i<mg.vexnum;i++)lg->vertices[i].firstarc=NULL;for(i=0;i<mg.vexnum;i++)for(j=mg.vexnum-1;j>=0;j--)if(mg.arcs[i][j]!=0){p=(ArcNode *)malloc(sizeof(ArcNode));p->adjvex=j;p->weight=mg.arcs[i][j];p->nextarc=lg->vertices[i].firstarc;lg->vertices[i].firstarc=p;}lg->vexnum=mg.vexnum;lg->arcnum=mg.arcnum;}void OutputMG(MGraph mg){int i,j;for(i=0;i<mg.vexnum;i++){for(j=0;j<mg.vexnum;j++)printf("%3d",mg.arcs[i][j]);printf("\n");}}void OutputLG(LGraph *lg){int i;ArcNode *p;for(i=0;i<lg->vexnum;i++){p=lg->vertices[i].firstarc;if(p) printf("%3d: ",i);while(p){printf("%3d",p->adjvex);p=p->nextarc;}printf("\n");}}void LDFS(LGraph *lg,int i){ArcNode *p;printf("%3d",i);visited[i]=1;p=lg->vertices[i].firstarc;while(p){if(!visited[p->adjvex])LDFS(lg,p->adjvex);p=p->nextarc;}}void MDFS(MGraph mg,int i){int j;printf("%3d",i);visited[i]=1;for(j=0;j<mg.vexnum;j++){if(mg.arcs[i][j]!=0&&visited[j]==0)MDFS(mg,j);}}void LBFS(LGraph *lg,int s){int i,v,w,front,rear;ArcNode *p;for(i=0;i<lg->vexnum;i++)visited[i]=0;front=rear=0;printf("%3d",s);visited[s]=1;queue[rear++]=s;while(front<rear){v=queue[front++];for(p=lg->vertices[v].firstarc;p!=NULL;p=p->nextarc){ w=p->adjvex;if(visited[w]==0){printf("%3d",w);visited[w]=1;queue[rear++]=w;}}}}void MBFS(MGraph mg,int s){int i,j,v,front,rear;for(i=0;i<mg.vexnum;i++)visited[i]=0;front=rear=0;printf("%3d",s);visited[s]=1;queue[rear++]=s;while(front<rear){v=queue[front++];for(i=0;i<mg.vexnum;i++)for(j=0;j<mg.vexnum;j++){if(mg.arcs[i][j]!=0&&visited[j]==0){printf("%3d",j);visited[j]=1;queue[rear++]=j;}}}}void main(){LGraph *lg;MGraph mg;int i;CreateMG(mg);CreatLG(lg,mg);printf("(1)当前图的邻接矩阵是:\n");OutputMG(mg);printf("(2)当前图的邻接表是:\n");OutputLG(lg);for(i=0;i<mg.vexnum;i++)visited[i]=0;getchar();printf("(3)邻接表表示的图的深度优先遍历序列是:");LDFS(lg,0);getchar();for(i=0;i<mg.vexnum;i++)visited[i]=0;printf("(4)邻接矩阵表示的图的深度优先遍历序列是:");MDFS(mg,0);getchar();printf("(5)邻接表表示的图的广度优先遍历序列是:");LBFS(lg,0);getchar();printf("(6)邻接矩阵表示的图的广度优先遍历序列是:");MBFS(mg,0);printf("\n");}。

数据结构实验六图

数据结构实验六图

实验六图的表示与遍历一、实验目的1、掌握图的邻接矩阵和邻接表表示2、掌握图的深度优先和广度优先搜索方法3、理解图的应用方法二、实验内容和要求1、阅读并运行下面程序,根据输入写出运行结果。

#include<stdio.h>#define N 20#define TRUE 1#define FALSE 0int visited[N];typedef struct /*队列的定义*/{int data[N];int front,rear;}queue;typedef struct /*图的邻接矩阵*/{int vexnum,arcnum;char vexs[N];int arcs[N][N];}graph;void createGraph(graph *g); /*建立一个无向图的邻接矩阵*/ void dfs(int i,graph *g); /*从第i个顶点出发深度优先搜索*/ void tdfs(graph *g); /*深度优先搜索整个图*/void bfs(int k,graph *g); /*从第k个顶点广度优先搜索*/ void tbfs(graph *g); /*广度优先搜索整个图*/void init_visit(); /*初始化访问标识数组*/void createGraph(graph *g) /*建立一个无向图的邻接矩阵*/ { int i,j;char v;g->vexnum=0;g->arcnum=0;i=0;printf("输入顶点序列(以#结束):\n");while((v=getchar())!='#'){g->vexs[i]=v; /*读入顶点信息*/i++;}g->vexnum=i; /*顶点数目*/for(i=0;i<g->vexnum;i++) /*邻接矩阵初始化*/for(j=0;j<g->vexnum;j++)g->arcs[i][j]=0;printf("输入边的信息:\n");scanf("%d,%d",&i,&j); /*读入边i,j*/while(i!=-1) /*读入i,j为-1时结束*/{g->arcs[i][j]=1;g->arcs[j][i]=1;scanf("%d,%d",&i,&j);}}void dfs(int i,graph *g) /*从第i个顶点出发深度优先搜索*/ {int j;printf("%c",g->vexs[i]);visited[i]=TRUE;for(j=0;j<g->vexnum;j++)if((g->arcs[i][j]==1)&&(!visited[j]))dfs(j,g);}void tdfs(graph *g) /*深度优先搜索整个图*/{int i;printf("\n从顶点%C开始深度优先搜索序列:",g->vexs[0]); for(i=0;i<g->vexnum;i++)if(visited[i]!=TRUE)dfs(i,g);}void bfs(int k,graph *g) /*从第k个顶点广度优先搜索*/{int i,j;queue qlist,*q;q=&qlist;q->rear=0;q->front=0;printf("%c",g->vexs[k]);visited[k]=TRUE;q->data[q->rear]=k;q->rear=(q->rear+1)%N;while(q->rear!=q->front){i=q->data[q->front];q->front=(q->front+1)%N;for(j=0;j<g->vexnum;j++)if((g->arcs[i][j]==1)&&(!visited[j])){printf("%c",g->vexs[j]);visited[j]=TRUE;q->data[q->rear]=j;q->rear=(q->rear+1)%N;}}}void tbfs(graph *g) /*广度优先搜索整个图*/{int i;printf("\n从顶点%C开始广度优先搜索序列:",g->vexs[0]); for(i=0;i<g->vexnum;i++)if(visited[i]!=TRUE)bfs(i,g);}void init_visit() /*初始化访问标识数组*/{int i;for(i=0;i<N;i++)visited[i]=FALSE;}int main(){graph ga;int i,j;createGraph(&ga);printf("无向图的邻接矩阵:\n");for(i=0;i<ga.vexnum;i++){for(j=0;j<ga.vexnum;j++)printf("%3d",ga.arcs[i][j]);printf("\n");}init_visit();tdfs(&ga);init_visit();tbfs(&ga);return 0;}▪ 根据右图的结构验证实验,输入:ABCDEFGH#0,1 0,20,5 1,31,4 2,52,63,74,7-1,-1▪ 运行结果:2、阅读并运行下面程序,补充拓扑排序算法。

数据结构---图的基本操作

数据结构---图的基本操作

数据结构---图的基本操作#include "stdio.h"#include "malloc.h"#define MAX_VERTEX_NUM 20#define OK 1#define error -1#define ERROR 0#define ErrorInput -2typedef int VertexType;typedef int Status;int CHIOCE;//用来接收用户的选择int VEXNUM,ARCNUM ; //用来接收用户输入的顶点和弧数目int i;typedef struct ArcNode{int adjvex; //该弧所指向的顶点的位置struct ArcNode *nextarc; //指向下一条弧的指针//InfoType *info; //相关信息}ArcNode;typedef struct VNode{VertexType data; //顶点信息(可放权值)ArcNode *firstarc; //指向第一条依附该顶点的弧的指针}VNode,AdjList[MAX_VERTEX_NUM];typedef struct{AdjList vertices;int vexnum,arcnum;//vexcount; //图的当前顶点和弧数和顶点计数,count记录真实结点个数int kind; //图的种类}ALGraph;typedef int ElemType;#define NULL 0typedef int ElemType;typedef struct QNode{ElemType data;struct QNode *next;}QNode, *QueuePtr;typedef struct{QueuePtr front;QueuePtr rear;}LinkQueue;bool InitQueue(LinkQueue &Q){Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));if(!Q.front) return false;Q.front->next=NULL;return true;}bool DestroyQueue(LinkQueue &Q){while(Q.front){Q.rear=Q.front->next;free(Q.front);Q.front=Q.rear;}return true;}bool EnQueue(LinkQueue &Q,ElemType data) {QueuePtr p;p=(QueuePtr)malloc(sizeof(QNode));if(!p) return false;p->data=data;p->next=NULL;Q.rear->next=p;Q.rear=p;return true;}bool DeQueue(LinkQueue &Q,ElemType &data) {QueuePtr p;if(Q.front==Q.rear) return false;p=Q.front->next;data=p->data;Q.front->next=p->next;if(Q.rear==p) Q.rear=Q.front;free(p);return true;}bool GetQueueTop(LinkQueue Q,ElemType &data){if(Q.front==Q.rear) return false;data=(Q.front->next)->data;return true;}bool QueueEmpty(LinkQueue &Q){if(Q.front==Q.rear) return true;return false;}void InitiateGraph(ALGraph *G){int i;G->vexnum=0;G->arcnum=0;for(i=0;i<MAX_VERTEX_NUM;i++){G->vertices[i].firstarc=NULL;}}/**********************在图G中第i个位置增添新顶点v *****************/void InsertVex(ALGraph *G,int i,VertexType v){if(i>=0&&i<MAX_VERTEX_NUM){G->vertices[i].data=v;//存储顶点数据元素vextexG->vexnum++; //个数加1 }elseprintf("顶点越界\n");}/***************************在图G中删除v*************************/Status DeleteVex(ALGraph &G,int v){//(事实上只是释放V-1处的空间并对v-1.data=-2做标记)int i=0;ArcNode *p,*q;for(i=0;i<G.vexnum;i++)//********删除以v为弧头的边*******{if(i==v) continue;if(G.vertices[i].firstarc==NULL) continue;if(G.vertices[i].firstarc->adjvex==v)//如果v为该节点的第一个临界弧所指向的顶点位置{p=G.vertices[i].firstarc;G.vertices[i].firstarc=p->nextarc;free(p);G.arcnum--;}else{ //q用来记录前一个弧,p为当前弧for(p=G.vertices[i].firstarc;p!=NULL;q=p,p=p->nextarc) {if(p->adjvex==v){q->nextarc=p->nextarc;free(p);G.arcnum--;break;//弧只有一条所以用break跳出}}}}//*********************删除以v为弧尾的边*************** if(G.vertices[v].firstarc!=NULL){p=G.vertices[v].firstarc;//p记录前一个弧q=p->nextarc;//q为当前弧//G.vertices[v].firstarc=NULL;while(1){free(p);G.arcnum--;if(q==NULL){break;}else{p=q;q=q->nextarc;}}}/*********************从数组中删除v节点**************************/for(i=v;i<G.vexnum-1;i++)G.vertices[i]=G.vertices[i+1];G.vexnum--;return OK;}void Connect(ALGraph &G,int v,int w){ArcNode *p,*q;if(G.vertices[v].firstarc==NULL){//如果是第一个节点为NULL,则直接建立p=(ArcNode *)malloc(sizeof(ArcNode));p->adjvex=w;p->nextarc=NULL;G.vertices[v].firstarc=p;}else{//如果不是NULL则进行遍历到最后一个弧for(p=G.vertices[v].firstarc;p!=NULL;q=p,p=p->nextarc);p=(ArcNode *)malloc(sizeof(ArcNode));p->adjvex=w;p->nextarc=NULL;q->nextarc=p;}}/*****在G中增添弧<v,w>,若G是无向的,则还增添对称弧<w,v>*******/int InsertArc(ALGraph &G,int v,int w){if(v<0||v>=G.vexnum||w<0||w>=G.vexnum){printf("参数错误\n");return 0;}else{Connect(G,v,w);G.arcnum++;if(G.kind==1){//如果是无向图则反向插入一个弧Connect(G,w,v);G.arcnum++;}printf("添加弧成功\n");return 1;}}/*******************删除节点v和w间的弧***********************************/Status Delete(ALGraph &G,int v,int w){ArcNode *p,*q;if(G.vertices[v].firstarc->adjvex==(w))//该弧是第一条依附顶点v的弧{p=G.vertices[v].firstarc;G.vertices[v].firstarc=p->nextarc;free(p);G.arcnum--;return OK;}else{//否则遍历找到这条弧for(p=G.vertices[v].firstarc;(p->adjvex!=w)&&(p->nextarc !=NULL);q=p,p=p->nextarc);if(p->adjvex==w){q->nextarc=p->nextarc;free(p);G.arcnum--;return ERROR;}elseprintf("该弧不存在");return OK;}}/*****在G中删除弧<v,w>,若G是无向的,则还删除对称弧<w,v>*******/Status DeleteArc(ALGraph &G,int v,int w){if(v<0||v>G.arcnum||w<0||w>G.arcnum){printf("参数错误");return ERROR;}else{Delete(G,v,w);if(G.kind==1){Delete(G,w,v);}return OK;}}/***********若G中存在顶点u,则返回该顶点在图中位置;否//则返回其它信息*******/int LocateVex(ALGraph G,int u){int i=0;while((G.vertices[i].data!=u)&&(i<G.vexnum))//遍历数组G.vertices[]查找ui++;if(G.vertices[i].data==u)return i;elsereturn ERROR;}/***********返回v的值*******************************/int GetVex(ALGraph G,int v){if(v<0||v>G.arcnum){printf("参数错误");return ERROR;}elsereturn G.vertices[v].data;}//**********对v赋值value*******************************Status SetVex(ALGraph &G,int v,int val){if(v<0||v>G.arcnum){printf("参数错误");return ERROR;}else{G.vertices[v].data=val;return OK;}}//******返回v的第一个邻接点。

《数据结构》基本操作指导

《数据结构》基本操作指导

目录指导一、单链表的操作----------------------------------------------------- 2指导二、栈及其应用------------------------------------------------------- 10指导三、串的基本操作---------------------------------------------------- 16指导四、二叉树的基本操作---------------------------------------------- 21指导五、图的存储和遍历------------------------------------------------- 31指导六、查找--------------------------------------------------------------- 41 指导七、排序--------------------------------------------------------------- 49指导一、单链表的操作一、指导目的1、掌握线性表的链式存储结构。

2、掌握利用链式存储结构实现线性表的基本操作。

3、掌握链式存储结构中的算法实现。

二、指导内容1、建立带头结点的单链表,并输出该单链表。

2、实现带头结点的单链表上的插入、删除、查找、修改操作。

三、操作指导1、定义单链表的结点结构单链表的结点结构可为一个结构体类型(slnodetype),其成员是数据域和指针域,数据域可以是整数。

2、模块划分和程序控制流程根据实验要完成的各功能,设置初始化、建立单链表、输出单链表、插入、删除、查找、修改和主函数8个模块,对于要完成的各功能,采用适当的人机界面,用循环和分支结构构成菜单进行选择。

3、初始化模块int initiate(slnodetype **h)该模块中产生一个只有头结点的空单链表,用指针h作为函数的参数返回,因为h是指针变参,所以在函数的参数位置要以二级指针出现。

图的基本操作及应用数据结构课程设计报告

图的基本操作及应用数据结构课程设计报告

算法与数据结构课程设计报告系(院):计算机科学学院专业班级:教育技术学1001班姓名:宋佳学号:201003901指导教师:詹泽梅设计时间:2012.6.16 - 2012.6.24设计地点:4号楼2号机房《算法与数据结构》课程设计任务书班级:教育技术11001课程设计题目:图的基本操作及应用数据结构课程设计是在学完数据结构课程之后的实践教学环节。

本实践教学是培养学生数据抽象能力,进行复杂程序设计的训练过程。

要求学生能对所涉及问题选择合适的数据结构、存储结构及算法,并编写出结构清楚且正确易读的程序,提高程序设计基本技能和技巧。

一.设计目的1.提高数据抽象能力。

根据实际问题,能利用数据结构理论课中所学到的知识选择合适的逻辑结构以及存储结构,并设计出有效解决问题的算法。

2.提高程序设计和调试能力。

学生通过上机实习,验证自己设计的算法的正确性。

学会有效利用基本调试方法,迅速找出程序代码中的错误并且修改。

3.初步了解开发过程中问题分析、整体设计、程序编码、测试等基本方法和技能。

二.设计任务设计一个基于DOS菜单的应用程序。

要利用多级菜单实现各种功能。

内容如下:1.无向图的基本操作及应用①创建无向图的邻接矩阵②创建无向图的邻接表③无向图的深度优先遍历④无向图的广度优先遍历2.有向图的基本操作及应用①创建有向图的邻接矩阵②创建有向图的邻接表③拓扑排序3.无向网的基本操作及应用①创建无向网的邻接矩阵②创建无向网的邻接表③求最小生成树4.有向网的基本操作及应用①创建有向网的邻接矩阵②创建有向网的邻接表③关键路径④单源最短路径三.设计指导第一步:根据设计任务,设计DOS菜单。

第二步:设计菜单(c语言)#include<stdio.h>void ShowMainMenu(){printf("\n");printf("**************图的基本操作及应用***************\n");printf("* 1 无向图的基本操作及应用*\n");printf("* 2 有向图的基本操作及应用*\n");printf("* 3 无向网的基本操作及应用*\n");printf("* 4 有向网的基本操作及应用*\n");printf("* 5 退出\n");printf("***********************************************\n");}void UDG(){int n;do{printf("\n");printf("**************无向图的基本操作及应用***************\n");printf("* 1 创建无向图的邻接矩阵*\n");printf("* 2 创建无向图的邻接表*\n");printf("* 3 无向图的深度优先遍历*\n");printf("* 4 无向图的广度优先遍历*\n");printf("* 5 退出\n");printf("***********************************\n");printf("请选择:");scanf("%d",&n);switch(n){case 1:printf("----------wait-------");break;case 2:printf("----------wait-------");break;case 3:printf("----------wait-------");break;case 4:printf("----------wait-------");break;case 5:break;default:printf("ERROR!");}}while(n!=5);}void DG(){int n;do{printf("\n");printf("**************有向图的基本操作及应用***************\n"); printf("* 1 创建有向图的邻接矩阵*\n"); printf("* 2 创建有向图的邻接表*\n");printf("* 3 拓扑排序*\n");printf("* 4 退出*\n");printf("*******************************\n");printf("请选择:");scanf("%d",&n);switch(n){case 1:printf("--------wait-------");break;case 2:printf("--------wait-------");break;case 3:printf("--------wait-------");break;case 4:break;default:printf("ERROR!");}}while(n!=4);}void UDN(){int n;do{printf("\n");printf("**************无向网的基本操作及***\n");printf("* 1 创建无向网的邻接矩阵*\n");printf("* 2 创建无向网的邻接表*\n");printf("* 3 Prim算法求最小生成树*\n");printf("* 4 kraskal算法求最小生成树*\n"); printf("* 5 退出\n");printf("*************************************\n"); printf("请选择:");scanf("%d",&n);switch(n){case 1:printf("---------wait-------");break;case 2:printf("--- ----wait-------");break;case 3:printf("---------wait-------");break;case 4:printf("---------wait-------");break;case 5:break;default:printf("ERROR!");}}while(n!=5);}void DN(){int n;do{printf("\n");printf("**************有向网的基本操作****\n"); printf("* 1 创建有向网的邻接矩阵*\n"); printf("* 2 创建有向网的邻接表*\n"); printf("* 3 关键路径*\n"); printf("* 4 单源顶点最短路径问题*\n"); printf("* 5 退出\n");printf("***********************************\n"); printf("请选择:");scanf("%d",&n);switch(n){case 1:printf("---------wait-------");break;case 2:printf("---------wait-------");break;case 3:printf("---------wait-------");break;case 4:printf("---------wait-------");break;case 5:break;default:printf("ERROR!");}}while(n!=5);}void main(){int n;do{ShowMainMenu();printf("请选择:");scanf("%d",&n);switch(n){case 1:UDG();break;case 2:DG();break;case 3:UDN();break;case 4:DN();break;case 5:break;default:printf("ERROR!");break;}}while(n!=5);}第三步:添加功能函数。

图的基本操作-数据实验报告书

图的基本操作-数据实验报告书

《数据结构》实验报告书实验内容:图的基本操作2011008141**计科111 **前言计算机编程中加工处理的对象是数据,而数据具有一定的组织结构,所以学习计算机编程仅仅了解计算机语言是不够的,还必须掌握数据的组织、存储和运算的一般方法,这便是数据结构课程中所研究的内容,也是我们编写计算机程序的重要基础,由于它对计算机学科起到承前启后的作用,因此本课程被列为计算机等相关专业最重要的专业基础课;同时数据结构是计算机专业教学的一门核心课程。

计算机各领域都要用到各种数据结构,而且要从事计算机科学与技术工作,尤其是计算机领域的软件开发工作,必须具备较强的数据结构基础。

数据结构课程内容丰富、学习量大,实践性强;隐含在各部分内容中的方法和技术多;算法设计具有动态性和抽象性等特点,看懂听明白与掌握会应用之间有相当大的一段距离。

所以学生必须多实践才能进一步加深对课程的理解,理解和掌握算法设计所需的方法和技术,为整个专业学习打下良好的基础。

一、实验目的1、使学生可以巩固所学的有关图的基本知识。

2、熟练掌握图的存储结构。

3、熟练掌握图的两种遍历算法。

二、实验内容[问题描述]对给定图,实现图的深度优先遍历和广度优先遍历。

[基本要求]以邻接表为存储结构,实现连通无向图的深度优先和广度优先遍历。

以用户指定的结点为起点,分别输出每种遍历下的结点访问序列。

【测试数据】由学生依据软件工程的测试技术自己确定。

三、实验前的准备工作1、掌握图的相关概念。

2、掌握图的逻辑结构和存储结构。

3、掌握图的两种遍历算法的实现。

四、实验报告要求1、实验报告要按照实验报告格式规范书写。

2、实验上要写出多批测试数据的运行结果。

3、结合运行结果,对程序进行分析。

三、算法设计1、程序所需头文件已经预处理宏定义和结构体定义如下#include<iostream.h>#define MaxVerNum 100struct edgenode{int endver;int inform;edgenode* edgenext;};struct vexnode{char vertex;edgenode* edgelink;};struct Graph{vexnode adjlists[MaxVerNum];int vexnum;int arcnum;};2、队列的定义及相关函数的实现struct QueueNode{int nData;QueueNode* next;};struct QueueList{QueueNode* front;QueueNode* rear;};void EnQueue(QueueList* Q,int e){QueueNode *q=new QueueNode;q->nData=e;q->next=NULL;if(Q==NULL)return;if(Q->rear==NULL)Q->front=Q->rear=q;else{Q->rear->next=q;Q->rear=Q->rear->next;}}void DeQueue(QueueList* Q,int* e){if (Q==NULL)return;if (Q->front==Q->rear){*e=Q->front->nData;Q->front=Q->rear=NULL;}else{*e=Q->front->nData;Q->front=Q->front->next;}}3、创建无向图void CreatAdjList(Graph* G){int i,j,k;edgenode* p1;edgenode* p2;cout<<"请输入顶点数和边数:"<<endl;cin>>G->vexnum>>G->arcnum;cout<<"开始输入顶点表:"<<endl;for (i=0;i<G->vexnum;i++){cin>>G->adjlists[i].vertex;G->adjlists[i].edgelink=NULL;}cout<<"开始输入边表信息:"<<endl;for (k=0;k<G->arcnum;k++){cout<<"请输入边<Vi,Vj>对应的顶点:";cin>>i>>j;p1=new edgenode;p1->endver=j;p1->edgenext=G->adjlists[i].edgelink;G->adjlists[i].edgelink=p1;p2=new edgenode;p2->endver=i;p2->edgenext=G->adjlists[j].edgelink;G->adjlists[j].edgelink=p2;//因为是无向图,所以有两次建立边表的过程}}4、深度优先遍历void DFS(Graph *G,int i,int visit[]){cout<<G->adjlists[i].vertex<<" ";visit[i]=1;edgenode *p=new edgenode;p=G->adjlists[i].edgelink;if(G->adjlists[i].edgelink&&!visit[p->endver]){DFS(G,p->endver,visit);}}void DFStraversal(Graph *G,char c)//深度优先遍历{cout<<"该图的深度优先遍历结果为:"<<endl;int visit[MaxVerNum];for(int i=0;i<G->vexnum;i++){visit[i]=0;//全部初始化为0,即未访问状态}int m;for (i=0;i<G->vexnum;i++){if (G->adjlists[i].vertex==c)//根据字符查找序号{m=i;DFS(G,i,visit);break;}}//继续访问未被访问的结点for(i=0;i<G->vexnum;i++){if(visit[i]==0)DFS(G,i,visit);}cout<<endl;}5、广度优先遍历void BFS(Graph* G,int v,int visit[]){QueueList *Q=new QueueList;Q->front=Q->rear=NULL;EnQueue(Q,v);while(Q->rear!=NULL){int e=0;DeQueue(Q,&e);cout<<G->adjlists[e].vertex<<" ";visit[e]=1;edgenode* p=new edgenode;p=G->adjlists[e].edgelink;if(p){int m=p->endver;if(m==0){EnQueue(Q,m);while(visit[m]==0){p=p->edgenext;if(p==NULL)break;m=p->endver;EnQueue(Q,m);}}}}}void BFStraversal(Graph *G,char c){cout<<"该图的广度优先遍历结果为:"<<endl;int visited[MaxVerNum];for (int i=0;i<G->vexnum;i++){visited[i]=0;}int m;for (i=0;i<G->vexnum;i++){if (G->adjlists[i].vertex==c){m=i;BFS(G,i,visited);break;}}//继续访问未被访问的结点for(i=0;i<G->vexnum;i++){if(visited[i]==0)BFS(G,i,visited);}cout<<endl;}四、调试与测试我们开始测试数据,如图:由图可知,我们得出了结果。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验6:图的操作算法
一、实验目的
1. 熟悉各种图的存储结构(邻接矩阵和邻接表)。

2.掌握图的深度优先和广度优先遍历算法。

3.掌握生成最小生成树的方法(普里姆算法、克鲁斯卡尔算法)。

4.掌握狄克斯特拉算法计算最短路径和最短路径长度的方法。

二、实验内容
1. 编写一个程序,输出下图的邻接矩阵,统计并输出各顶点的度。

1
23
4
0具体效果如下:
2.假设下图不带权有向图采用邻接矩阵g存储,设计实现以下功能的算法:
(1)输出有向图的邻接矩阵。

(2)求出图中每个顶点的入度。

(3)求出图中每个顶点的出度。

(4)求出图中出度为0的顶点数。

1
23
4
具体效果如下:Array
三、实验要求
1.独立完成实验程序的编写与调试;
2.实验完成后填写实验报告,学习委员按学号从小到大的顺序提交。

相关文档
最新文档