#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);
}
}
/*
*/
有向网实现(c语言)
最新推荐文章于 2022-11-14 17:57:57 发布