拓扑排序--C语言
来源:互联网 发布:淘宝企业旗舰店 编辑:程序博客网 时间:2024/05/06 12:50
基本思想:
1、在有向图中选一个没有前驱(入度为0)的顶点且输出;
2、从图中删除该顶点和所有以它为尾的边。
重复上述两步,直至全部顶点均已输出,或者当前图中不存在无前驱的顶点为止(此时说明有向图中存在环)。
#include <stdio.h>#include <stdlib.h>#include <stdbool.h>/*--有向无环图拓扑排序--*/ #define MAX_VERTEX_NUM 20typedef char VertexType;typedef int StackElem;//邻接表存储图 typedef struct ArcNode{ int adjvex; struct ArcNode *nextarc;}ArcNode;typedef struct VNode{ int indegree; //图中顶点入度 VertexType data; ArcNode *firstarc;}VNode,AdjList[MAX_VERTEX_NUM];typedef struct{ AdjList vertices; int vernum,arcnum;}ALGraph;//创建有向图int locateVex(ALGraph alg,char v){ int i; for(i=0;i<alg.vernum;i++) { if(alg.vertices[i].data == v) return i; } return -1; } void createAOVGraph(ALGraph *alg){ int i,j,k; char v1,v2; ArcNode *p,*s; printf("输入有向图顶点数个和边数:"); scanf("%d %d",&(alg->vernum),&(alg->arcnum)); getchar(); printf("输入顶点名称\n"); for(k=0;k<alg->vernum;k++) { printf("输入第%d个顶点名称:",k); scanf("%c",&(alg->vertices[k].data)); alg->vertices[k].firstarc = NULL; alg->vertices[k].indegree = 0; getchar(); } printf("输入边信息v1 v2\n"); for(k=0;k<alg->arcnum;k++) { printf("输入d第%d条边的起止顶点名称:",k); scanf("%c %c",&v1,&v2); i = locateVex(*alg,v1); j = locateVex(*alg,v2); p = (ArcNode*)malloc(sizeof(ArcNode)); p->adjvex = j; p->nextarc = NULL; if(alg->vertices[i].firstarc == NULL) { alg->vertices[i].firstarc = p; } else { s = alg->vertices[i].firstarc; while(s->nextarc != NULL) s = s->nextarc; s->nextarc = p; } alg->vertices[j].indegree += 1; //结点j的入度增加1 getchar(); } } //打印有向图 void print(ALGraph G) { int i; ArcNode *p; printf("图的邻接链表(顶点名称 入度:邻接点)\n"); for(i=0;i<G.vernum;i++) { printf("%c %d:",G.vertices[i].data,G.vertices[i].indegree); p = G.vertices[i].firstarc; while(p!= NULL) { printf("%c ",G.vertices[p->adjvex].data); p = p->nextarc; } printf("\n"); } printf("\n"); } //有向图进行拓扑排序,若有向图没有回路则输出图的一个拓扑排序以OK结尾,否则输出序列以error结束//为避免重复检测入度为0的顶点,设一个栈暂存入度为0的顶点typedef struct SNode{ StackElem index; struct SNode *snext;}SNode,*PSNode;typedef struct Stack{ PSNode top; PSNode bottom; }Stack,*PStack;bool stackEmpty(PStack ps){ if(ps->bottom == ps->top) return true; return false;}PStack initStack(){ PStack ps = (PStack)malloc(sizeof(Stack)); PSNode p = (PSNode)malloc(sizeof(SNode)); if(p==NULL && ps ==NULL) { printf("initstack error!\n"); exit(-1); } p->snext = NULL; ps->bottom = ps->top = p; return ps; } void push(PStack ps,StackElem index){ PSNode p = (PSNode)malloc(sizeof(SNode)); if(p == NULL) { printf("push error!\n"); exit(-1); } p->index = index; p->snext = ps->top; ps->top = p;}StackElem pop(PStack ps){ if(stackEmpty(ps)) { printf("stack is NULL\n"); exit(-1); } else { PSNode p = ps->top; StackElem index = p->index; ps->top = p->snext; free(p); return index; }}//拓扑排序 void topologicalSort(ALGraph G){ printf("拓扑排序序列:"); int i,count=0,index; //count对栈中输出顶点计数 ArcNode *p; StackElem k; PStack ps = initStack(); for(i=0;i<G.vernum;i++) { if(G.vertices[i].indegree==0) //入度为0的顶点入栈 push(ps,i); } while(!stackEmpty(ps)) { index = pop(ps); printf("%c ",G.vertices[index].data); ++count; for(p=G.vertices[index].firstarc;p!=NULL;p=p->nextarc) { k = p->adjvex; if((--G.vertices[k].indegree)==0) //对第index个顶点的每个邻接点的入度减1,若邻接点入度为0,则入栈 push(ps,k); } } printf("\n"); if(count < G.vernum) printf("有向图中存在环ERROR!\n"); else printf("OK!\n"); } int main(){ ALGraph alg; createAOVGraph(&alg); print(alg); topologicalSort(alg); return 0;}
0 0
- 拓扑排序C语言
- 拓扑排序--C语言
- c语言实现拓扑排序
- C语言 拓扑排序基础
- 拓扑排序的c语言实现
- 拓扑排序(一)之 C语言详解
- 拓扑排序的c语言实现
- 拓扑排序的c语言实现
- 拓扑排序(C语言实现)
- C语言拓扑排序的实现
- 拓扑排序(C语言 邻接表)
- 拓扑排序(C语言 邻接矩阵存储)
- 图邻接表C语言实现 拓扑排序
- 数据结构之---C语言实现拓扑排序AOV图
- 值得说的一个问题:C语言实现拓扑排序
- c语言实现拓扑排序(《数据结构》算法7.12)
- C语言实现有向无环图的拓扑排序算法
- 拓扑排序 C实现
- 9.2.1
- 1045-Access denied for user'root'@'xxxxxxxx' using password:YES
- 在 CentOS 上搭建FTP服务器
- 故障转移集群的仲裁
- 1 Hadoop简介
- 拓扑排序--C语言
- 二维字符串排序详解
- Scala入门随笔一
- shared_ptr:线程安全、循环引用
- HDU1669 Jamie's Contact Groups 二分法+二分图的多重匹配
- You Get 需要用到的记录
- 杭电 2017 ( 字符串统计 ) java
- 数据库的join连接
- ubuntu下制作MATLAB快捷方式