有向网实现(c语言)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define INF 10000


typedef struct node{
	struct node *next;
	int vertex;
	int data;
}Gnode;
typedef struct{
	int *data;
	int top;
	int size;
}stack,*Stack;
typedef struct{
	Gnode *firstArc;
	char vexs[20];
}ALnode;

typedef struct{
	ALnode node[20];
	int arcs[20][20]; 
	int verNum;
	int arcNum;
}ALGraph;

typedef struct{
	int *data;
	int front;
	int rear;
	int size;
}queue,*Queue;
A

void create_ALGraph(ALGraph *G){
	int i,j,v,w,d;
	printf("输入结点数 边数:\n");
	scanf("%d %d",&G->verNum,&G->arcNum);
	for(i=0;i<G->verNum;i++){
		printf("输入结点名称:\n");
		fflush(stdin);
		scanf("%s",G->node[i].vexs);
		G->node[i].firstArc=NULL;
	}
	for(i=0;i<G->verNum;i++)
		for(j=0;j<G->verNum;j++){
			if(i==j)G->arcs[i][j]=0;
			else G->arcs[i][j] = INF;
		}
	for(i=0;i<G->arcNum;i++){
		Gnode *p=(Gnode*)malloc(sizeof(Gnode));
		p->next=NULL;
		printf("输入邻接边信息:");
		fflush(stdin);
		scanf("%d %d %d",&v,&w,&d);
		p->vertex=w;
		p->data=d;
		p->next= G->node[v].firstArc;
		G->node[v].firstArc = p;
		G->arcs[v][w] = d;
	}
}

void print(ALGraph G){
	int i,j;
	for(i=0;i<G.verNum;i++)printf("%s ",G.node[i].vexs);
	printf("\n");
	for(i=0;i<G.verNum;i++){
		Gnode *p=G.node[i].firstArc;
		while(p){
			printf("%s->%s %d\n",G.node[i].vexs,G.node[p->vertex].vexs,p->data);
			p = p->next;
		}
	}
}

void dfs(ALGraph G, int v, int visited[]){
	int i;
	printf("%s ",G.node[v].vexs);
	visited[v] = 1;
	for(i=0;i<G.verNum;i++){
		Gnode *p = G.node[v].firstArc;
		while(p){
			if(!visited[p->vertex])dfs(G,p->vertex,visited);
			p = p->next;
		}
	}
}

void dfs_(ALGraph G, int v, int visited[], int count[]){
	int i;
	count[v]++;
	visited[v]=1;
	for(i=0;i<G.verNum;i++){
		Gnode *p = G.node[v].firstArc;
		while(p){
			if(!visited[p->vertex])dfs_(G,p->vertex,visited,count);
			p = p->next;
		}
	}
}


void Tarjan(ALGraph G,int u,int DFN[], int Low[],int visited[], Stack s,int *index){
	int i,v;
	(*index)++;
	DFN[u] = Low[u] = *index;
	visited[u] = 1;
	Push(s,u);

		Gnode *p = G.node[u].firstArc;
		while(p){
			if(!DFN[p->vertex]){
				Tarjan(G,p->vertex,DFN,Low,visited,s,index);
				Low[u] = Low[u] > Low[p->vertex] ? Low[p->vertex] : Low[u]; 
			}
			else if(inStack(s,p->vertex)){
				Low[u] = Low[u] > DFN[p->vertex] ? DFN[p->vertex] : Low[u];
			}
			p = p->next;
		}


	if(DFN[u] == Low[u]){

		do{
			v = Pop(s);
			printf("%s ",G.node[v].vexs);
			visited[v] = 0;
		}while(u!=v);
		printf("\n");
	}
} 

void Trajan_ConnectedComponent(ALGraph G){
	int index,Low[G.verNum],DFN[G.verNum],visited[G.verNum],i,j;
	stack s;
	initStack(&s,G.verNum);
	
	index=0;
	for(i=0;i<G.verNum;i++)DFN[i] = 0;
	for(j=0;j<G.verNum;j++)visited[j] = 0;
	for(i=0;i<G.verNum;i++){	
		//for(j=0;j<G.verNum;j++)visited[j] = 0;
		if(!DFN[i])Tarjan(G,0,DFN,Low,visited,&s,&index);
	}


}
void deepTraver(ALGraph G, int v){
	int i,j,visited[G.verNum];
	for(i=0;i<G.verNum;i++)visited[i] = 0;
	dfs(G,v,visited);
	for(i=0;i<G.verNum;i++){
		if(!visited[i] && i!= v){
			dfs(G,i,visited);
			printf("\n");
		}
	}
}

void BFS(ALGraph G, int v, int visited[]){
	queue q;
	initQueue(&q,G.verNum);
	printf("%s ",G.node[v].vexs);
	visited[v] = 1;
	EnQueue(&q,v);
	while(!isQueueEmpty(q)){
		int w = DeQueue(&q);
		Gnode *p =G.node[w].firstArc;
		while(p){
			if(!visited[p->vertex]){
				visited[p->vertex]=1;
				printf("%s ",G.node[p->vertex].vexs);
				EnQueue(&q,p->vertex);
			}
			p = p->next;
		}
	}	
}

void BFSearch(ALGraph G, int v){
	int i,visited[G.verNum];
	for(i=0;i<G.verNum;i++)visited[i] = 0;
	BFS(G,v,visited);
	for(i=0;i<G.verNum;i++){
		if(!visited[i] && i!=v)BFS(G,i,visited);
		
	}
}
int getDegree_out(ALGraph G, int v){
	int count=0,i;
	Gnode *p = G.node[v].firstArc;
	while(p){
		count++;
		p = p->next;
	}
	return count;
}
int getDegree_in(ALGraph G, int v){
	int count=0,i;
	Gnode *p;
	for(i=0;i<G.verNum;i++){
		if(i!=v){
			p = G.node[i].firstArc;
			while(p){
				if(p->vertex==v)count++;
				p = p->next;
			}
		}
	}
	return count;
}

void getNeighbour(ALGraph G, int v){
	int i;
	for(i=0;i<G.verNum;i++){
		Gnode *p=G.node[i].firstArc;
		while(p){
			if(i==v){
				printf("%s->%s\n",G.node[v].vexs,G.node[p->vertex].vexs);
			}
			else if(p->vertex==v){
				printf("%s->%s\n",G.node[i].vexs,G.node[p->vertex].vexs);
			}
			p = p->next;
		}
	}
}

void Dijistra(ALGraph G, int v){
	int i,j,n,flag,k;
	int path[G.verNum][G.verNum];
	int dist[G.verNum];
	for(i=0;i<G.verNum;i++)
		for(j=0;j<G.verNum;j++)path[i][j] = -1;
	for(i=0;i<G.verNum;i++){
		dist[i] = G.arcs[v][i];
		if(dist[i]!=0)path[i][0] = v;
		if(dist[i] !=0 && dist[i] !=INF)path[i][1] = i;
	}
	while(flag){
		k=0;
		int min = INF;
		for(i=0;i<G.verNum;i++){
			if(dist[i]!=0 && dist[i]<min){
				k = i;
				min = dist[i];
			}
		}
		printf("k:%d 第%d条最短路径长度为%d--(",k,++n,min);
		for(j=0;j<G.verNum;j++)
			if(path[k][j]!=-1)printf("%s ",G.node[path[k][j]].vexs);
		printf("\b)\n");
		for(j=0;j<G.verNum;j++){
			if(j!=k&& dist[j]!=0){
				if(dist[k]+G.arcs[k][j]<dist[j]){
					dist[j] = dist[k]+G.arcs[k][j];
					for(i=0;i<G.verNum;i++)path[j][i] = path[k][i];
					for(i=0;i<G.verNum && path[j][i] != -1;)i++;
					path[j][i] = j;
				}
			}
		}
		dist[k] = 0;
		flag = 0;
		for(j=0;j<G.verNum;j++)if(dist[j]!=0 && dist[j]<INF)flag=1;
		
	}
	
}
#define N 10
void Floyd(ALGraph G, int path[N][N]){
	int A[G.verNum][G.verNum];
	int i,j,v;
	for(i=0;i<G.verNum;i++){
		for(j=0;j<G.verNum;j++){
			A[i][j] = G.arcs[i][j];
			path[i][j] = -1;
		}
	}
	for(v=0;v<G.verNum;v++)
		for(i=0;i<G.verNum;i++)
			for(j=0;j<G.verNum;j++){
				if(A[i][j]>A[i][v]+A[v][j]){
					A[i][j] = A[i][v]+A[v][j];
					path[i][j] = v;
				}
			}
}
void printPath(ALGraph G, int v, int w, int path[N][N]){
	if(path[v][w]==-1){
		printf("%s->%s ",G.node[v].vexs,G.node[w].vexs);
	}
	else{
		int mid = path[v][w];
		printPath(G,v,mid,path);
		printPath(G,mid,w,path);
	}
}

void menu(){
	printf("-------------menu--------------\n");
	printf("1)创建该有向网的邻接表\n");
	printf("2)输出该有向网的顶点和邻接表\n");
	printf("3)求该有向网的连通分量\n");
	printf("4)指定一个顶点,进行深度遍历\n");
	printf("5)指定一个顶点,进行广度遍历\n");
	printf("6)求给定顶点的度,邻接边\n");
	printf("7)给定出发点,基于Dijstral算法求最短路径\n");
	printf("8)给定出发点,基于FLoyd求最短路径\n");
	printf("输入0退出\n");
} 
int main(){
	int visited[20]={0};
	int path[N][N];
	ALGraph G;
	int choice,i,j;
	menu();
	printf("请输入命令:\n");
	scanf("%d",&choice);
	while(choice){
		switch(choice){
			case 1:
				create_ALGraph(&G);	
				break;
			case 2:
				print(G);
				break;
			case 3:
				printf("连通分量:\n");
				Trajan_ConnectedComponent(G);
				break;
			case 4:
				printf("输入结点:\n");
				scanf("%d",&i);
				deepTraver(G,i);
				printf("\n");
				break;
			case 5:
				printf("输入结点:\n");
				scanf("%d",&i);
				BFSearch(G,i);
				printf("\n");
				break;
			case 6:
				printf("输入结点:\n");
				scanf("%d",&i);
				printf("入度:%d 出度:%d\n",getDegree_in(G,i),getDegree_out(G,i));
				getNeighbour(G,i);
				break;
			case 7:
				printf("输入结点:\n");
				scanf("%d",&i);
				Dijistra(G,i);
				break;
			case 8:
				printf("输入两个结点:\n");
				scanf("%d %d",&i,&j);
				Floyd(G,path);
				printPath(G,i,j,path);
				printf("\n");
				break;
		}
	menu();
	printf("请输入命令:\n");
	scanf("%d",&choice);
	}
}


/*

*/
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值