数据结构实验六 图的应用及其实现
实验六 图的基本操作

南京信息工程大学实验(实习)报告图的基本操作一、实验目的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:广度优先搜索遍历)五、实验总结…。
实验六 图基本操作的编程实现

盛年不重来,一日难再晨。
及时宜自勉,岁月不待人。
实验六图基本操作的编程实现【实验目的】图基本操作的编程实现要求:图基本操作的编程实现(2学时,验证型),掌握图的建立、遍历、插入、删除等基本操作的编程实现,存储结构可以在顺序结构、链接结构、联合使用多种结构等中任选,也可以全部实现。
也鼓励学生利用基本操作进行一些应用的程序设计。
【实验性质】验证性实验(学时数:2H)【实验内容】编程对图进行存储(邻接矩阵或邻接表都可以,由学生自由选择),之后可以询问任何两个结点之间是否有通路和路径数。
设计一个将图形转成邻接链表的程序。
设计一个深度优先搜索法来查找图形的程序。
设计一个广度优先搜索法来查找一个图形的程序。
鼓励开发出难度更高的程序。
【思考问题】1.图的定义和特性?2.图的主要存储结构是什么?是独立的某种还是多种数据结构的综合?3.图的主要遍历思路是哪些?4.举出图的应用范例?【参考代码】(一)将一个将图转成邻接矩阵的程序./*程序构思:*//*用户输入结点与各个边,再将边转成邻接矩阵。
*/#include<stdio.h>#define Max 6 /* 定义最大可输入的结点个数 */int Graph[Max][Max]; /*图形邻接数组 *//*===============================================*//*输出邻接矩阵数据===============================*//*===============================================*/void print_M_Graph(){int i,j;printf("Vertice");for (i=0;i<Max;i++)printf("%3d",i);printf("\n");for(i=0;i<Max;i++){printf("%4d ",i);for (j=0;j<Max;j++)printf("%3d" );printf("\n");}}/*===============================================*//*以邻接矩阵建立图形=============================*//*===============================================*/void Create_M_Graph(int Verticel,int Vertice2){Graph[Verticel][Vertice2]=1; /* 将矩阵内容设为1 */}/*===============================================*//*主程序=========================================*//*===============================================*/void main(){int Source; /*起始顶点*/int Destination; /*终止顶点*/int i,j;for (i=0;i<Max;i++)for (j=0;j<Max;j++)Graph[i][i]=0;while(1){printf("please input the Edge's source:");scanf("%d",&Source);if(Source ==-1)break;printf("Please input the Edge's Destination:");scanf("%d",&Destination);if(Source==Destination) /* 出错:自身循环*/printf("***Error***: Self Loop!! \n");else if (Source >= Max || Destination >= Max) /* 出错:超出范围*/ printf ("***Error***: out of range!! \n");else /*调用建立邻接数组 */Create_M_Graph(Source,Destination);}printf("##Graph##\n");; /*调用输出邻接数组数据*/}/*希望的结果 *//*please input the Edge's source:0 *//*Please input the Edge's Destination:4 *//*please input the Edge's source:1 *//*Please input the Edge's Destination:0 *//*please input the Edge's source:1 *//*Please input the Edge's Destination:4 *//*please input the Edge's source:2 *//*Please input the Edge's Destination:1 *//*please input the Edge's source:3 *//*Please input the Edge's Destination:2 *//*please input the Edge's source:4 *//*Please input the Edge's Destination:3 *//*please input the Edge's source:-1 *//*##Graph## *//*Vertice 0 1 2 3 4 5 *//* 0 0 0 0 0 1 0 *//* 1 1 0 0 0 1 0 *//* 2 0 1 0 0 0 0 *//* 3 0 0 1 0 0 0 *//* 4 0 0 0 1 0 0 *//* 5 0 0 0 0 0 0 */(二) 将一个将图转成邻接表的程序./*程序构思:*//*用户输入结点与各个边,再将边转成邻接链表。
数据结构实验六 图的应用及其实现

实验六图的应用及其实现一、实验目的1.进一步功固图常用的存储结构。
2.熟练掌握在图的邻接表实现图的基本操作。
3.理解掌握AOE网在邻接表上的实现及解决简单的应用问题。
二、实验内容[题目]:从键盘上输入AOE网的顶点和有向边的信息,建立其邻接表存储结构,输出其关键路径和关键路径长度。
试设计程序实现上述AOE网类型定义和基本操作,完成上述功能。
三、实验步骤(一)、数据结构与核心算法的设计描述本实验题目是基于图的基本操作以及邻接表的存储结构之上,着重拓扑排序算法的应用,做好本实验的关键在于理解拓扑排序算法的实质及其代码的实现。
(二)、函数调用及主函数设计以下是头文件中数据结构的设计和相关函数的声明:typedef struct ArcNode // 弧结点{int adjvex;struct ArcNode *nextarc;InfoType info;}ArcNode;typedef struct VNode //表头结点{VertexType vexdata;ArcNode *firstarc;}VNode,AdjList[MAX_VERTEX_NUM];typedef struct //图的定义{AdjList vertices;int vexnum,arcnum;int kind;}MGraph;typedef struct SqStack //栈的定义{SElemType *base;SElemType *top;int stacksize;}SqStack;int CreateGraph(MGraph &G);//AOE网的创建int CriticalPath(MGraph &G);//输出关键路径(三)、程序调试及运行结果分析(四)、实验总结在做本实验的过程中,拓扑排具体代码的实现起着很重要的作用,反复的调试和测试占据着实验大量的时间,每次对错误的修改都加深了对实验和具体算法的理解,自己的查错能力以及其他各方面的能力也都得到了很好的提高。
数据结构图的实验报告

数据结构图的实验报告数据结构图的实验报告引言:数据结构图是计算机科学中重要的概念之一。
它是一种用图形表示数据元素之间关系的数据结构,广泛应用于算法设计、程序开发和系统优化等领域。
本实验报告旨在介绍数据结构图的基本原理、实验过程和结果分析。
一、实验目的本次实验的主要目的是掌握数据结构图的基本概念和操作方法,以及通过实验验证其在解决实际问题中的有效性。
具体而言,我们将通过构建一个社交网络关系图,实现对用户关系的管理和分析。
二、实验方法1. 确定数据结构在本次实验中,我们选择了无向图作为数据结构图的基础。
无向图由顶点集和边集组成,每条边连接两个顶点,且没有方向性。
2. 数据输入为了模拟真实的社交网络,我们首先需要输入一组用户的基本信息,如姓名、年龄、性别等。
然后,根据用户之间的关系建立边,表示用户之间的交流和联系。
3. 数据操作基于构建好的数据结构图,我们可以进行多种操作,如添加用户、删除用户、查询用户关系等。
这些操作将通过图的遍历、搜索和排序等算法实现。
三、实验过程1. 数据输入我们首先创建一个空的无向图,并通过用户输入的方式逐步添加用户和用户关系。
例如,我们可以输入用户A和用户B的姓名、年龄和性别,并建立一条边连接这两个用户。
2. 数据操作在构建好数据结构图后,我们可以进行多种操作。
例如,我们可以通过深度优先搜索算法遍历整个图,查找与某个用户具有特定关系的用户。
我们也可以通过广度优先搜索算法计算某个用户的社交网络影响力,即与该用户直接或间接相连的其他用户数量。
3. 结果分析通过实验,我们可以观察到数据结构图在管理和分析用户关系方面的优势。
它能够快速地找到用户之间的关系,帮助我们了解用户的社交网络结构和影响力。
同时,数据结构图也为我们提供了一种可视化的方式来展示用户之间的关系,使得分析更加直观和易于理解。
四、实验结果通过实验,我们成功构建了一个社交网络关系图,并实现了多种数据操作。
我们可以根据用户的姓名、年龄和性别等信息进行查询,也可以根据用户之间的关系进行遍历和排序。
数据结构实验报告图的应用

实验题目:图的应用一、实验目的和任务1 掌握图的邻接表和邻接矩阵存储;2 掌握图的拓扑排序算法;二、实验内容及原理1以下两项内容选做一项。
2 请按照书中介绍的拓扑排序算法,完成P303页第5题。
3 给定某一个图,完成其深度优先搜索遍历和广度优先搜索遍历,每种遍历都必须在邻接矩阵和邻接表中完成。
四、实验数据及程序代码#include <iostream.h>#include <stdlib.h>#include <strstrea.h>#include <string.h>#include <stdio.h>const int MaxVertexNum=10;typedef int WeightType;struct edgenode{int adjvex;WeightType weight;edgenode*next;};typedef edgenode *adjlist[MaxVertexNum];void InitAdjoin(adjlist GL)//初始化{for(int i=0;i<MaxVertexNum;i++)GL[i]=NULL;}void CreatAdjoin(adjlist GL,int n,char*s,int k1,int k2)//生成邻接表{istrstream sin(s);char c1,c2,c3;WeightType w;edgenode*p;sin>>c1;if(k2==0){do{sin>>c1>>i>>c2>>j>>c3;p=new edgenode;p->adjvex=j;p->weight=1;p->next=GL[i];GL[i]=p;if(k1==0){p=new edgenode;p->adjvex=i;p->weight=1;p->next=GL[j];GL[j]=p;}sin>>c1;}while(c1==',');}else{do{sin>>c1>>i>>c2>>j>>c3>>w;p=new edgenode;p->adjvex=j;p->weight=w;p->next=GL[i];GL[i]=p;if(k1==0){p=new edgenode;p->adjvex=i;p->weight=w;p->next=GL[j];GL[j]=p;}sin>>c1;}while(c1==',');}}void PrintAdjion(adjlist GL, int n,int k1, int k2) {edgenode*p;cout<<"V={";for(i=0; i<n-1; i++) cout<<i<<',';cout<<n-1<<'}'<<endl;cout<<"E={";for(i=0;i<n;i++){if(k2==0){p=GL[i];while(p){j=p->adjvex;if(k1==0){if(i<j) cout<<'('<<i<<','<<j<<')'<<',';}elsecout<<'<'<<i<<","<<j<<'>'<<',';p=p->next;}}else{p=GL[i];while(p){j=p->adjvex;if(k1==0){if(i<j) cout<<'('<<i<<','<<j<<')'<<p->weight<<',';}elsecout<<'<'<<i<<','<<j<<'>'<<p->weight<<',';p=p->next;}}}cout<<'}'<<endl;}void Toposort(adjlist GL , int n){int i,j,k,top,m=0;edgenode*p;int*d=new int[n];for(i=0;i<n;i++) d[i]=0;for(i=0;i<n;i++){p=GL[i];while(p!=NULL){j=p->adjvex;d[i]++;p=p->next;//cout<<j;}}top=-1;for(i=0;i<n;i++)if(d[i]==0){d[i]=top; top=i;}while(top!=-1){j=top;top=d[top];cout<<j<<' ';m++;p=GL[j];while(p!=NULL){k=p->adjvex;d[k]--;if(d[k]==0){d[k]=top;top=k;}p=p->next;}}cout<<endl;cout<<top<<endl;cout<<m<<endl;cout<<n<<endl;if(m<n) cout<<"The network has a cycle!"<<endl;delete []d;}void main(){int n,k1,k2;cout<<"输入待处理图的顶点数:";cin>>n;cout<<"输入图的有无向和有无权选择(0为无,非0为有):";cin>>k1>>k2;adjlist gl;InitAdjoin(gl);cout<<"输入图的边集:";FILE *p;p=fopen("d:\\1.txt","r+");char *a=new char[100];while (!feof(p)){fscanf(p,"%s ",a);cout<<a;}cout<<endl;//cin>>a;CreatAdjoin(gl,n,a,k1,k2);Toposort(gl,n);}五、实验数据分析及处理六、实验结论与感悟(或讨论)图的邻接矩阵,邻接表和边集数组表示各有利弊,具体运用时,要根据图的稠密和稀疏程度以及算法的要求进行选择。
数据结构实验报告

数据结构实验报告一、实验目的数据结构是计算机科学中重要的基础课程,通过本次实验,旨在深入理解和掌握常见数据结构的基本概念、操作方法以及在实际问题中的应用。
具体目的包括:1、熟练掌握线性表(如顺序表、链表)的基本操作,如插入、删除、查找等。
2、理解栈和队列的特性,并能够实现其基本操作。
3、掌握树(二叉树、二叉搜索树)的遍历算法和基本操作。
4、学会使用图的数据结构,并实现图的遍历和相关算法。
二、实验环境本次实验使用的编程环境为具体编程环境名称,编程语言为具体编程语言名称。
三、实验内容及步骤(一)线性表的实现与操作1、顺序表的实现定义顺序表的数据结构,包括数组和表的长度等。
实现顺序表的初始化、插入、删除和查找操作。
2、链表的实现定义链表的节点结构,包含数据域和指针域。
实现链表的创建、插入、删除和查找操作。
(二)栈和队列的实现1、栈的实现使用数组或链表实现栈的数据结构。
实现栈的入栈、出栈和栈顶元素获取操作。
2、队列的实现采用循环队列的方式实现队列的数据结构。
完成队列的入队、出队和队头队尾元素获取操作。
(三)树的实现与遍历1、二叉树的创建以递归或迭代的方式创建二叉树。
2、二叉树的遍历实现前序遍历、中序遍历和后序遍历算法。
3、二叉搜索树的操作实现二叉搜索树的插入、删除和查找操作。
(四)图的实现与遍历1、图的表示使用邻接矩阵或邻接表来表示图的数据结构。
2、图的遍历实现深度优先遍历和广度优先遍历算法。
四、实验结果与分析(一)线性表1、顺序表插入操作在表尾进行时效率较高,在表头或中间位置插入时需要移动大量元素,时间复杂度较高。
删除操作同理,在表尾删除效率高,在表头或中间删除需要移动元素。
2、链表插入和删除操作只需修改指针,时间复杂度较低,但查找操作需要遍历链表,效率相对较低。
(二)栈和队列1、栈栈的特点是先进后出,适用于函数调用、表达式求值等场景。
入栈和出栈操作的时间复杂度均为 O(1)。
2、队列队列的特点是先进先出,常用于排队、任务调度等场景。
数据结构实验六 图

实验六图一、实验目的1、掌握图的基本存储方法和相关术语2、掌握图的两种搜索路径的遍历方法3、理解最小生成树的有关概念及普里姆(Prim)和克鲁斯卡尔算法4、掌握图的有关应用二、实验要求1、认真阅读程序。
2、上机调试,并运行程序。
3、保存和截图程序的运行结果,并结合程序进行分析。
三、实验内容和基本原理1、实验6.1 建立无向图的邻接矩阵存并输出给出一个无向图,求它的邻接矩阵(见参考程序1):2、实验6.2 建立图的邻接存储并在此基础上实现图的深度优先遍历和广度优先遍历#include<stdio.h>#include<stdlib.h>#define MAX 20typedef int VexType;typedef VexType Mgraph[MAX][MAX];void creat_mg(Mgraph G);void output_mg(Mgraph G);Mgraph G1;int n,e,v0;void main(){creat_mg(G1);output_mg(G1);}void creat_mg(Mgraph G){int i,j,k;printf("\n 请输入无向图的顶点数和边数,如: 6,5:");scanf("%d,%d",&n,&e);for(i=1;i<=n;i++)for(j=1;j<=n;j++)G[i][j]=0;for(k=1;k<=e;k++){printf("\n请输入每条边的两个顶点编号,如:2,5 :");scanf("%d,%d",&i,&j);G[i][j]=1;G[j][i]=1;}}void output_mg(Mgraph G){int i,j;for(i=1;i<n;i++){printf("\n");for(j=1;j<=n;j++)printf("%5d",G[i][j]);}printf("\n");}#include<stdio.h>#include<stdlib.h>#define MAX 20typedef int VexType;typedef struct Vnode{VexType data;struct Vnode *next;}Vnode;typedef Vnode Lgraph[MAX];typedef struct{int V[MAX];int front;int rear;}Queue;void creat_L(Lgraph G);void output_L(Lgraph G);void dfsL(Lgraph G,int v);Lgraph Ga;int n,e,visited[MAX];void main(){int v1,i;for(i=0;i<MAX;i++)visited[i]=0;creat_L(Ga);output_L(Ga);printf("\n请输入深度优先遍历的出发点:");scanf("%d",&v1);printf("\n深度优先遍历的结果为:");dfsL(Ga,v1);for(i=0;i<MAX;i++)visited[i]=0;printf("\n请输入广度优先遍历的出发点:");scanf("%d",&v1);printf("\n广度优先遍历的结果为:");dfsL(Ga,v1);}void creat_L(Lgraph G){Vnode *p,*q;int i,j,k;printf("\n请输入图的顶点数和边数:");scanf("%d,%d",&n,&e);for(i=1;i<=n;i++){G[i].data=i;G[i].next=NULL;}for(k=1;k<=e;k++){printf("请输入每条边的关联顶点编号:");scanf("%d,%d",&i,&j);p=(Vnode *)malloc(sizeof(Vnode));p->data=i;p->next=G[j].next;G[j].next=p;q=(Vnode *)malloc(sizeof(Vnode));q->data=j;q->next=G[i].next;G[i].next=q;}}void output_L(Lgraph G){int i;Vnode *p;for(i=1;i<=n;i++){printf("\n与[%d]关联的顶点有:",i);p=G[i].next;while(p!=NULL){printf("%5d",p->data);p=p->next;}}}void initqueue(Queue *q){q->front=-1;q->rear=-1;}int quempty(Queue *q){if(q->front==q->rear){return 1;}else{return 0;}}void enqueue(Queue *q,int e){if((q->rear+1)%MAX==q->front)printf("队列满!\n");else{q->rear=(q->rear+1)%MAX;q->V[q->rear]=e;}}int dequeue(Queue *q){int t;if(q->front==q->rear){printf("队列空!\n");return 0;}else{q->front=(q->front+1)%MAX;t=q->V[q->front];return t;}}void dfsL(Lgraph G,int v){Vnode *p;printf("%d->",G[v].data);visited[v]=1;p=G[v].next;while(p){v=p->data;if(visited[v]==0)dfsL(G,v);p=p->next;}}void bfsL(Lgraph g,int v){int x;Vnode *p;Queue *q=(Queue *)malloc(sizeof(Queue));initqueue(q);printf("\n %d->",g[v].data);visited[v]=1;enqueue(q,v);while(!quempty(q)){x=dequeue(q);p=g[x].next;while(p){v=p->data;if(visited[v]==0){printf("%d->",g[v].data);visited[v]=1;enqueue(q,v);}p=p->next;}}printf("\n");}四、实验验证与练习1、在N条边的无向图的邻接表存储中,边表中结点的总数为()。
实验六 图及其应用

实验六图及其应用数据结构实验六图及其应用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、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验六图的应用及其实现一、实验目的1.进一步功固图常用的存储结构。
2.熟练掌握在图的邻接表实现图的基本操作。
3.理解掌握AOE网在邻接表上的实现及解决简单的应用问题。
二、实验内容[题目]:从键盘上输入AOE网的顶点和有向边的信息,建立其邻接表存储结构,输出其关键路径和关键路径长度。
试设计程序实现上述AOE网类型定义和基本操作,完成上述功能。
三、实验步骤(一)、数据结构与核心算法的设计描述本实验题目是基于图的基本操作以及邻接表的存储结构之上,着重拓扑排序算法的应用,做好本实验的关键在于理解拓扑排序算法的实质及其代码的实现。
(二)、函数调用及主函数设计以下是头文件中数据结构的设计和相关函数的声明:typedef struct ArcNode // 弧结点{int adjvex;struct ArcNode *nextarc;InfoType info;}ArcNode;typedef struct VNode //表头结点{VertexType vexdata;ArcNode *firstarc;}VNode,AdjList[MAX_VERTEX_NUM];typedef struct //图的定义{AdjList vertices;int vexnum,arcnum;int kind;}MGraph;typedef struct SqStack //栈的定义{SElemType *base;SElemType *top;int stacksize;}SqStack;int CreateGraph(MGraph &G);//AOE网的创建int CriticalPath(MGraph &G);//输出关键路径(三)、程序调试及运行结果分析(四)、实验总结在做本实验的过程中,拓扑排具体代码的实现起着很重要的作用,反复的调试和测试占据着实验大量的时间,每次对错误的修改都加深了对实验和具体算法的理解,自己的查错能力以及其他各方面的能力也都得到了很好的提高。
最终实验结果也符合实验的预期效果。
四、主要算法流程图及程序清单1、主要算法流程图:2、程序清单:创建AOE网模块:int CreateGraph(MGraph &G) //创建有向网{int i,j,k,Vi,Vj;ArcNode *p;cout<<"\n请输入顶点的数目、边的数目"<<endl;cin>>G.vexnum>>G.arcnum;for(i=0;i<G.vexnum;++i){ G.vertices[i].vexdata=i; G.vertices[i].firstarc=NULL;} for(k=0;k<G.arcnum;++k){cout<<"请输入第"<<k+1<<"条边的始点:"; cin>>Vi;cout<<"请输入第"<<k+1<<"条边的终点:"; cin>>Vj;i=Vi; j=Vj;i--; j--;p=(ArcNode *)malloc(sizeof(ArcNode));if(!p){ cout<<"Overflow!"; return (ERROR); }p->adjvex=j;p->nextarc=G.vertices[i].firstarc;p->info=NULL;G.vertices[i].firstarc=p;cout<<"请输入第"<<k+1<<"条边的权值:";cin>>p->info;}return (OK);}输出关键路径模块:int ve[MAX_VERTEX_NUM]; //存储事件的最早可能发生时间int vl[MAX_VERTEX_NUM]; //存储事件的最迟允许开始时间int InitStack(SqStack &S) //初始化栈{S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType)); if(!S.base){ cout<<"初始化栈失败!"; return(ERROR); }S.top=S.base;S.stacksize=STACK_INIT_SIZE;return(OK);}int Push(SqStack &S,SElemType e) //压栈{if(S.top-S.base>S.stacksize){S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT *sizeof(SElemType)));if(!S.base){ cout<<endl<<"Overflow!"; return(ERROR); }S.top=S.base+S.stacksize;S.stacksize+=STACKINCREMENT;}*S.top++=e;return(OK);}int Pop(SqStack &S,SElemType &e) //弹出栈{if(S.top==S.base){cout<<"栈满 !"; return(ERROR); }e=*--S.top;return(OK);}int StackEmpty(SqStack S) //判断栈是否为空{if(S.top==S.base) return (YES);else return(NO);}void FindInDegree(MGraph G,int *indegree) //求各个顶点的入度{int i;for(i=0;i<G.vexnum;i++)indegree[i]=0;for(i=0;i<G.vexnum;i++)while(G.vertices[i].firstarc){indegree[G.vertices[i].firstarc->adjvex]++;G.vertices[i].firstarc=G.vertices[i].firstarc->nextarc;}}int TopologicalOrder(MGraph G,SqStack &T) //拓扑排序{int indegree[MAX_VERTEX_NUM];int i,count=0,j,k;ArcNode *p;SqStack S;FindInDegree(G,indegree);InitStack(S);for(i=0;i<G.vexnum;++i)if(!indegree[i]) Push(S,i); //入度为0的顶点入栈InitStack(T);for(i=0;i<=G.vexnum-1;i++) ve[i]=0;while(!StackEmpty(S)){Pop(S,j);Push(T,j); ++count;for(p=G.vertices[j].firstarc; p; p=p->nextarc){ k=p->adjvex;if(!(--indegree[k])) Push(S,k);if(ve[j]+p->info>ve[k]) ve[k]=ve[j]+p->info;}}if(count<G.vexnum) return(ERROR) ;else return(OK);}int CriticalPath(MGraph &G) //输出关键路径函数{int i,j,k,dut;int ee,el;char tag;ArcNode *p;SqStack T;if(!TopologicalOrder(G,T)) return(ERROR);for(i=0;i<=G.vexnum-1;i++)vl[i]=ve[G.vexnum-1];while(!StackEmpty(T)){for(Pop(T,j),p=G.vertices[j].firstarc; p; p=p->nextarc){k=p->adjvex;dut=p->info;if(vl[k]-dut<vl[j])vl[j]=vl[k]-dut;}}for(j=0;j<G.vexnum;++j)for(p=G.vertices[j].firstarc; p; p=p->nextarc){k=p->adjvex; dut=p->info;ee=ve[j]; el=vl[k]-dut;tag=(ee==el)?'*':' ';if(tag=='*')cout<<"V"<<j+1<<"->V"<<k+1<<" "<<"活动最早可能开始时间"<<ee<<" 最迟允许开始时间"<<el<<" "<<endl;}}。