数据结构--C语言--图的深度优先遍历,广度优先遍历,拓扑排序,用prime算法实现最小生成树,用迪杰斯特拉算法实现关键路径和关键活动的求解,最短路径

实验七  图的深度优先遍历选做,验证性实验,4学时)

  1. 实验目的

熟悉图的数组表示法和邻接表存储结构,掌握构造有向图、无向图的算法 ,在掌握以上知识的基础上,熟悉图的深度优先遍历算法,并实现。

  1. 实验内容

(1)图的数组表示法定义及基本操作的实现。

(2)图的邻接表表示法定义及基本操作的实现。

(3)写函数实现图的深度优先遍历(分别在两种结构上)

(4)在邻接表上实现拓扑排序、关键路径的求法,在邻接矩阵上实现最短路经、最小生成树的求法。

//邻接矩阵表示法存储无向图 深度优先搜索 最短路径 最小生成树 
#include
#define MAX_VERTEX_NUM 20
#define INT_MAX unsigned(-1)>>1
typedef int VRType;
typedef int Status;
typedef char VertexType;
typedef char* InfoType;
typedef int PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef int ShortPathTable[MAX_VERTEX_NUM];

int visited[MAX_VERTEX_NUM];//全局变量 访问标志数组 

typedef enum{DG,DN,UDG,UDN}GraphKind;

typedef struct{
	VertexType adjvex;
	int lowcost;	
}Closedge[MAX_VERTEX_NUM];//存放所有已经插入的节点到当前顶点的权值最小的那条边 终点就是i位置上的顶点 adj存放边的起点 lowcost存放最小的权值 

typedef struct{
	VRType adj;//顶点关系 
	InfoType info;//该弧相关信息的指针 --权值 
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
  
typedef struct{
	VertexType vexs[MAX_VERTEX_NUM];//顶点向量 
	AdjMatrix arcs;//邻接矩阵 
	int vexnum,arcnum;
	GraphKind kind;//图的种类标志 
}MGraph;

int LocateVex(MGraph G,VertexType a){
		for(int i=0;i=0;w=NextAdjVex(G,i,w))
		if(!visited[w])
			DFS(G,w);
	return 0;
}
Status DFSTraverse(MGraph G,Status (*Visit)(VertexType c)){//深度优先遍历算法
	for(int i=0;iclosedge[m].lowcost) minlocate = m;
		}
		
		k = minlocate;//选出权值最小的边的终点的下标
		printf("\n%c %c",closedge[k].adjvex,G.vexs[k]);
		
		closedge[k].lowcost = 0;//第k顶点已经插入在树里了 所以不会存在以第k顶点为终点的待插入的边了 
		for(int j=0;j0)&&(D[newin]+G.arcs[newin][j].adj
//邻接表表示法存储有向图 广度优先搜索拓 扑排序 关键路径 
#include
#include
#define MAXSIZE 20 
#define MAX_VERTEX_NUM 20

typedef int Status;
typedef int QElemType;//队列里放的是元素在一位数组里的下标 
typedef char VertexType;
typedef int SElemType;
typedef enum{DG,DN,UDG,UDN}GraphKind;

typedef struct{
	QElemType *base;//队列的基地址 
	int front;//队头下标 相当于队头指针 指向队列头元素 
	int rear;//队尾下标 指向队列尾元素的下一个位置 
}SqQue;

typedef struct ArcNode{//表结点 
	int adjvex;//该弧指向的顶点的位置 
	int weight;//权重 
	int info;
	struct ArcNode* next; 
}ArcNode;

typedef struct{//头结点 
	VertexType data;//顶点信息 
	ArcNode *firstarc;//指向第一个邻接点 
}VNode,AdjList[MAX_VERTEX_NUM];
 
typedef struct{
	AdjList vertices;
	int vexnum,arcnum;
	int kind;
}ALGraph;

typedef struct{
	SElemType *base;
	SElemType *top;
	int stacksize; 
}SqStack;

int visited[MAX_VERTEX_NUM];
int ve[MAX_VERTEX_NUM];
int vl[MAX_VERTEX_NUM];
int indegree[MAX_VERTEX_NUM];
SqStack S,T;//S是零入度顶点栈 T是拓扑序列顶点栈 

int LocateVex(ALGraph G,VertexType v){
	for(int i=0;iadjvex;
}

int NextAdjVex(ALGraph G,int v,int w){
	ArcNode *p;
	for(p=G.vertices[v].firstarc;p;p=p->next) 
		if(p->adjvex==w&&p->next) return p->next->adjvex;
	return -1;
}

Status Visit(VertexType c){
	printf("%c",c);
}

//初始化一个空栈
Status InitStack(SqStack &S){
	S.base = (SElemType *)malloc(MAX_VERTEX_NUM*sizeof(SElemType));
	if(!S.base) exit(-1);
	S.top = S.base;
	S.stacksize = MAX_VERTEX_NUM;
	return 1;
}

//判空 
Status StackEmpty(SqStack S){
	return S.base==S.top; 
}

//入栈
Status Push(SqStack &S,SElemType e){
	*S.top++ = e;
	return 1;
}
//出栈
Status Pop(SqStack &S,SElemType &i){
	if(S.base==S.top){
		printf("空栈!\n");
		return 0;
	}
	i = *--S.top;
	return 1;
}

Status CreatDN(ALGraph &G){
	int IncInfo;
	printf("请输入顶点数 边数 边上是否有相关信息(是1否0)\n");
	scanf("%d%d%d",&G.vexnum,&G.arcnum,&IncInfo);//顶点个数 边数 
	//先构造顶点向量
	fflush(stdin);
	printf("请输入顶点集:\n");
	for(int i=0;iinfo));
		headlo = LocateVex(G,head);
		pnew->adjvex = LocateVex(G,tail);
		pnew->next = G.vertices[headlo].firstarc;
		G.vertices[headlo].firstarc = pnew;//头插法插入表结点 
	} 
}
//构造一个空的循环队列
Status InitQueue(SqQue &q){
	q.base = (QElemType *)malloc(MAXSIZE*sizeof(QElemType));
	if(!q.base) exit(0);
	q.front = q.rear = 0;//空队列 两指针均指向下表为0的位置
	return 1; 
}
//出队列 
Status DeQueue(SqQue &q,int &e){
	if(q.rear==q.front) return 0;
	e = q.base[q.front];
	q.front = (q.front+1)%MAXSIZE;
	return 1;
}
//入队列 
Status EnQueue(SqQue &q,int e){
	if((q.rear+1)%MAXSIZE==q.front){
		printf("队列已满!\n");
		return 0;
	}
	q.base[q.rear] = e;
	q.rear = (q.rear+1)%MAXSIZE;
	return 1;
}

Status BFSTraverse(ALGraph G,Status (*Visit)(VertexType c)){//深度优先遍历算法
	for(int i=0;i=0;j=NextAdjVex(G,u,j)){
					if(!visited[j]){
						visited[j] = 1;
						Visit(G.vertices[j].data);
						EnQueue(q,j);
					}
				} 
			} 
		}
	}
}

Status FindInDegree(ALGraph G){
	ArcNode *p;
	for(int i=0;inext)
			indegree[p->adjvex]++;
}

Status TopologicalSort(ALGraph G){
	SqStack S;
	int i,j,count;
	ArcNode* p;
	
	FindInDegree(G);
	InitStack(S);
	
	for(i=0;inext){
			j = p->adjvex;
			if(!(--indegree[j])) Push(S,j);
		}
	}
	if(countnext){
			j = p->adjvex;
			if((ve[i]+p->info)>ve[j]) ve[j] = ve[i] + p->info;//计算入度为0的顶点的邻接点的最早开始时间 
			indegree[j]--; 
			if(!indegree[j]){
				Push(S,j);	
			}
		}
	} 
	if(countnext){
			k = p->adjvex;
			dut = p->info;//关键活动的时间
			if(vl[k]-dutnext){
			k = p->adjvex;
			dut = p->info;
			ee = ve[j];
			el = vl[k]-dut;
			if(ee==el) printf("     %c\t           %c\t            %d\t             %d\n",G.vertices[j].data,G.vertices[k].data,dut,ee);
		}
	}
}

main(){
	ALGraph G;
	CreatDN(G);
	printf("\n\n广度优先搜索:");
	BFSTraverse(G,Visit);
	printf("\n\n拓扑排序结果:");
	TopologicalSort(G);
	printf("\n\n关键活动:\n"); 
	CriticalPath(G);
	return 0;
}

 

你可能感兴趣的:(数据结)