1、/ 图的邻接表存储表示 #define MAX_NAME 3 / 顶点字符串的最大长度+1 #define MAX_VERTEX_NUM 20#define STACK_INIT_SIZE 10 / 存储空间初始分配量 #define STACKINCREMENT 2 / 存储空间分配增量 typedef int InfoType; / 存放网的权值 typedef char VertexTypeMAX_NAME; / 字符串类型 typedef enumDG,DN,AG,ANGraphKind; / 有向图,有向网,无向图,无向网 typedef struct ArcNode int adj
2、vex; / 该弧所指向的顶点的位置 struct ArcNode *nextarc; / 指向下一条弧的指针 InfoType *info; / 网的权值指针) ArcNode; / 表结点 typedef struct VNode VertexType data; / 顶点信息 ArcNode *firstarc; / 第一个表结点的地址,指向第一条依附该顶点的弧的指针 VNode,AdjListMAX_VERTEX_NUM;/ 头结点 typedef struct AdjList vertices; int vexnum,arcnum; / 图的当前顶点数和弧数 int kind; /
3、图的种类标志 ALGraph;/ 若G中存在顶点u,则返回该顶点在图中位置;否则返回-1。int LocateVex(ALGraph G,VertexType u) int i; for(i=0;iG.vexnum;+i) if(strcmp(u,G.verticesi.data)=0) return i; return -1;/ 采用邻接表存储结构,构造没有相关信息的图G(用一个函数构造4种图)。int CreateGraph(ALGraph *G) int i,j,k; int w; / 权值 VertexType va,vb; ArcNode *p; printf(请输入图的类型(有向图
4、:0,有向网:1,无向图:2,无向网:3): ); scanf(%d,&(*G).kind);请输入图的顶点数和边数:(空格)n%d%d, &(*G).vexnum, &(*G).arcnum);请输入%d个顶点的值(小于%d个字符):n,(*G).vexnum,MAX_NAME); for(i = 0; i (*G).vexnum; +i) / 构造顶点向量 scanf(%s, (*G).verticesi.data); (*G).verticesi.firstarc = NULL; if(*G).kind = 1 | (*G).kind = 3) / 网 printf(请顺序输入每条弧(边
5、)的权值、弧尾和弧头(以空格作为间隔): else / 图 请顺序输入每条弧(边)的弧尾和弧头(以空格作为间隔): for(k = 0;k adjvex = j; if(*G).kind = 1 | (*G).kind = 3) / 网 p-info = (int *)malloc(sizeof(int); *(p-info) = w; elseinfo = NULL; / 图 nextarc = (*G).verticesi.firstarc; / 插在表头 (*G).verticesi.firstarc = p; if(*G).kind = 2) / 无向图或网,产生第二个表结点 p =
6、(ArcNode*)malloc(sizeof(ArcNode);adjvex = i; if(*G).kind = 3) / 无向网 p-info = (int*)malloc(sizeof(int); *(p- else / 无向图 nextarc = (*G).verticesj.firstarc; (*G).verticesj.firstarc = p; return 1;void Display(ALGraph G) / 输出图的邻接表G。 switch(G.kind) case DG:有向图n break; case DN:有向网n case AG:无向图n case AN:无向网
7、n%d个顶点:,G.vexnum); G.vexnum; +i)%s ,G.verticesi.data);n%d条弧(边):, G.arcnum); i+) p = G.verticesi.firstarc; while(p) if(G.kind adjvex.data); if(G.kind = DN) / 网 printf(:%d , *(p-info); else / 无向(避免输出两次) if(i adjvex) %s%s G.verticesp- if(G.kind = AN) / 网 printf(,*(p- p=p-nextarc;void FindInDegree(ALGra
8、ph G,int indegree) / 求顶点的入度。 i+) indegreei=0; / 赋初值 p=G.verticesi.firstarc; indegreep-adjvex+;typedef int SElemType; / 栈类型 typedef struct SqStack / 栈的顺序存储表示 SElemType *base; / 在栈构造之前和销毁之后,base的值为NULL SElemType *top; / 栈顶指针 int stacksize; / 当前已分配的存储空间,以元素为单位 SqStack; / 顺序栈int InitStack(SqStack *S) /
9、构造一个空栈S / 为栈底分配一个指定大小的存储空间 (*S).base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType); if( !(*S).base ) exit(0); / 存储分配失败 (*S).top = (*S).base; / 栈底与栈顶相同表示一个空栈 (*S).stacksize = STACK_INIT_SIZE;/ 若栈S为空栈(栈顶与栈底相同的),则返回1,否则返回0。int StackEmpty(SqStack S) if(S.top = S.base) return 1; else return 0;i
10、nt Push(SqStack *S, SElemType e) / 插入元素e为新的栈顶元素。 if(*S).top - (*S).base = (*S).stacksize) / 栈满,追加存储空间 (*S).base = (SElemType *)realloc(*S).base, (*S).stacksize + STACKINCREMENT) * sizeof(SElemType); if( ! exit(0); / 存储分配失败 (*S).top = (*S).base+(*S).stacksize; (*S).stacksize += STACKINCREMENT; *(*S).
11、top)+=e; / 这个等式的+ * 优先级相同,但是它们的运算方式,是自右向左/ 若栈不空,则删除S的栈顶元素,用e返回其值,并返回1;否则返回0。int Pop(SqStack *S,SElemType *e) if(*S).top = (*S).base) *e = *-(*S).top;/ 有向图G采用邻接表存储结构。若G无回路,则输出G的顶点的一个拓扑序/ 列并返回1, 否则返回0。int TopologicalSort(ALGraph G) int i,k,count,indegreeMAX_VERTEX_NUM; SqStack S; FindInDegree(G,indegr
12、ee); / 对各顶点求入度indegree0.vernum-1 InitStack(&S); / 初始化栈 +i) / 建零入度顶点栈S if(!indegreei) Push(&S,i); / 入度为0者进栈 count=0; / 对输出顶点计数 while(!StackEmpty(S) / 栈不空 Pop(&S,&i); / 输出i号顶点并计数 +count; for(p=G.verticesi.firstarc;p;p=p-nextarc) / 对i号顶点的每个邻接点的入度减1 k=p-adjvex; if(!(-indegreek) / 若入度减为0,则入栈 S,k); if(cou
13、ntG.vexnum)此有向图有回路n无回路,此图的拓扑序nint main() ALGraph f;请选择有向图n CreateGraph(&f); Display(f); TopologicalSort(f); system(pause return 0;求一个无向图G的连通分量的个数/无向图的邻接表存储表示 #define MAX_NAME 3 / 顶点字符串的最大长度+1 #define TRUE 1#define FALSE 0int visitedMAX_VERTEX_NUM;/访问标志数组 / 第一个表结点的地址,指向第一条依附该顶点的弧的指针 请输入无向图的顶点数和边数: (*
14、G).verticesi.firstarc = p; / 无向图产生第二个表结点 p = (ArcNode*)malloc(sizeof(ArcNode); (*G).verticesj.firstarc = p;/ 输出图的邻接表G。void Display(ALGraph G) if(i void DFS(ALGraph G,int v)/从第v个顶点出发递归地深度优先遍历图G。 visitedv = TRUE;/访问第v个顶点 for(p=G.verticesv.firstarc; if(!visitedp-adjvex) DFS(G,p-adjvex);/对v尚未访问的邻接点递归调用D
15、FS void DFSTraverse(ALGraph G)/对图G作深度优先遍历。 int v,count=0; for (v=0;v+v) visitedv=FALSE;+v)visitedv) DFS(G,v); count+;/对连通分量进行计数 无向图G的连通分量的个数为:,count); DFSTraverse(f);五、运行输出结果:请选择有向图 0(空格)4 4请输入4个顶点的值(小于3个字符):1230 20 12 33 0有向图4个顶点:0 1 2 34条弧(边):0 1 0 22 33 0此有向图有回路请按任意键继续. . .5 4请输入5个顶点的值(小于3个字符):451 22 41 43 5无向图5个顶点:1 2 3 4 514 122435六、心得与体会:这次上机实验,难度较大,但是经过自己的不懈努力,收获还是颇多的。首先是对于图的有了更加清晰认识,其次,在程序设计上面也有了很大程度的提高。对于栈、队等也有了进一步的系统化认
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1