求无向连通图的生成树(用c语言设计程序)

求无向连通图的生成树(用c语言设计程序),第1张

不知道你要的是不是这个 完整实现如下: #define INFINITY 65535typedef int status# include <stdio.h># include <stdlib.h># include <conio.h># include "string.h"# define maxlen 10typedef struct{ char vexs[maxlen][maxlen]/*顶点信息集合,我们用它来存入顶点名字*/ int vexnum,arcnum/*顶点数和边数*/ int arcs[maxlen][maxlen]/*邻接矩阵*/}graph//定位输入节点的名称int LocateVex(graph G,char u[maxlen]){int ifor(i=0i<G.vexnum++i) if(strcmp(u,G.vexs[i])==0) return i return -1} void prim(graph &g)/*最小生成树*/{ int i,j,k,min,w,flag int lowcost[maxlen]/*权值*/ int closet[maxlen]/*最小生成树结点*/ char va[maxlen],vb[maxlen] //初始化邻接矩阵 //printf("请输入顶点数和边数:\n") //scanf("%d%d",&g.vexnum,&g.arcnum) g.vexnum=6 g.arcnum=10 printf("请输入顶点信息(我们这里指名字):\n") for(int j=0j<g.vexnumj++) scanf("%s",g.vexs[j]) for(i=0i<g.vexnum++i) for(j=0j<g.vexnum++j)//初始化邻接矩阵 { g.arcs[i][j]=INFINITY //任意两个顶点间距离为无穷大。 }//for /*printf("请输入%d条弧的弧模慎尾 弧头 权值(以空格为间隔)\n",g.arcnum) for(k=0k<g.arcnum++k) { scanf("%s%s%d%*c",va,vb,&w)//用%*c吃掉回车符 i=LocateVex(g,va) //注意,这里定行信义的是char va[5],也就是说va是首地旦带敬址 j=LocateVex(g,vb) g.arcs[i][j]=w//无向网 g.arcs[j][i]=w//无向网 }//for */ g.arcs[0][1]=6 g.arcs[1][0]=6 g.arcs[0][2]=1 g.arcs[2][0]=1 g.arcs[0][3]=5 g.arcs[3][0]=5 g.arcs[1][2]=5 g.arcs[2][1]=5 g.arcs[1][4]=3 g.arcs[4][1]=3 g.arcs[2][3]=5 g.arcs[3][2]=5 g.arcs[2][4]=6 g.arcs[4][2]=6 g.arcs[2][5]=4 g.arcs[5][2]=4 g.arcs[3][5]=2 g.arcs[5][3]=2 g.arcs[4][5]=6 g.arcs[5][4]=6 printf("最小生成树的边为:\n") for(i=1i<g.vexnumi++) { lowcost[i]=g.arcs[0][i]closet[i]=1 } closet[0]=0//初始v1是属于集合U的,即设它是最小生成树中节点的一员 j=1//V是顶点集合 for(i=1i<g.vexnumi++) { min=lowcost[j]k=ifor(j=1j<g.vexnumj++) if(lowcost[j]<min&&closet[j]!=0) { min=lowcost[j]k=j //记录当前要加入集合U的节点号 }//if if(i==1) flag=0 else flag=closet[k]//还没有加入集合U的节点的closet[]值是 //记录了上一次加入集合U的节点号 closet[k]=0//将刚刚找到的点加入到集合U中 printf("(%s,%s),",g.vexs[k],g.vexs[flag])//输出刚刚找到的最小生成树树枝 for(j=1j<g.vexnumj++)if(g.arcs[k][j]<lowcost[j]&&closet[j]!=0) { lowcost[j]=g.arcs[k][j]//更新lowcost[]的值,且在还没有加入U集合的//的closet[]中记录刚刚加入U集合的节点号以备//下一循环中输出用 closet[j]=k } }} int main(){graph gprim(g)}

*/

#include <stdio.h>

#include <malloc.h>

// 输出有向图的一个拓扑序列。实现算法7.12的程序

// 图的邻接表存储表示

#define MAX_NAME 3 // 顶点字符串的最大长度+1

#define MAX_VERTEX_NUM 20

typedef int InfoType // 存放网的权值

typedef char VertexType[MAX_NAME] // 字符串类型

typedef enum{DG,DN,AG,AN}GraphKind// {有向顷碰图,有向网,无向图,无向网}

typedef struct ArcNode

{

int adjvex // 该弧所指向的顶点的位置

struct ArcNode *nextarc // 指向下一条弧的指针

InfoType *info // 网的权值指针)

}ArcNode // 表结点

typedef struct VNode

{

VertexType data // 顶点信息

ArcNode *firstarc // 第一个表结点的地址,指向第一条依附该顶点的弧的指针槐乎败

}VNode,AdjList[MAX_VERTEX_NUM]// 头结点

typedef struct

{

AdjList vertices

int vexnum,arcnum // 图的当前顶点数和铅颤弧数

int kind // 图的种类标志

}ALGraph

// 若G中存在顶点u,则返回该顶点在图中位置否则返回-1。

int LocateVex(ALGraph G,VertexType u)

{

int i

for(i=0i<G.vexnum++i)

if(strcmp(u,G.vertices[i].data)==0)

return i

return -1

}

// 采用邻接表存储结构,构造没有相关信息的图G(用一个函数构造4种图)。

int CreateGraph(ALGraph *G)

{

int i,j,k

int w // 权值

VertexType va,vb

ArcNode *p

printf("请输入图的类型(有向图:0,有向网:1,无向图:2,无向网:3): ")

scanf("%d",&(*G).kind)

printf("请输入图的顶点数和边数:(空格)\n")

scanf("%d%d", &(*G).vexnum, &(*G).arcnum)

printf("请输入%d个顶点的值(<%d个字符):\n",(*G).vexnum,MAX_NAME)

for(i = 0i <(*G).vexnum++i) // 构造顶点向量

{

scanf("%s", (*G).vertices[i].data)

(*G).vertices[i].firstarc = NULL

}

if((*G).kind == 1 || (*G).kind == 3) // 网

printf("请顺序输入每条弧(边)的权值、弧尾和弧头(以空格作为间隔):\n")

else // 图

printf("请顺序输入每条弧(边)的弧尾和弧头(以空格作为间隔):\n")

for(k = 0k <(*G).arcnum++k) // 构造表结点链表

{

if((*G).kind==1||(*G).kind==3) // 网

scanf("%d%s%s",&w,va,vb)

else // 图

scanf("%s%s",va,vb)

i = LocateVex(*G,va)// 弧尾

j = LocateVex(*G,vb)// 弧头

p = (ArcNode*)malloc(sizeof(ArcNode))

p->adjvex = j

if((*G).kind == 1 || (*G).kind == 3) // 网

{

p->info = (int *)malloc(sizeof(int))

*(p->info) = w

}

else

p->info = NULL// 图

p->nextarc = (*G).vertices[i].firstarc// 插在表头

(*G).vertices[i].firstarc = p

if((*G).kind >= 2) // 无向图或网,产生第二个表结点

{

p = (ArcNode*)malloc(sizeof(ArcNode))

p->adjvex = i

if((*G).kind == 3) // 无向网

{

p->info = (int*)malloc(sizeof(int))

*(p->info) = w

}

else

p->info = NULL// 无向图

p->nextarc = (*G).vertices[j].firstarc// 插在表头

(*G).vertices[j].firstarc = p

}

}

return 1

}

// 输出图的邻接表G。

void Display(ALGraph G)

{

int i

ArcNode *p

switch(G.kind)

{

case DG: printf("有向图\n")

break

case DN: printf("有向网\n")

break

case AG: printf("无向图\n")

break

case AN: printf("无向网\n")

}

printf("%d个顶点:\n",G.vexnum)

for(i = 0i <G.vexnum++i)

printf("%s ",G.vertices[i].data)

printf("\n%d条弧(边):\n", G.arcnum)

for(i = 0i <G.vexnumi++)

{

p = G.vertices[i].firstarc

while(p)

{

if(G.kind <= 1) // 有向

{

printf("%s→%s ",G.vertices[i].data,

G.vertices[p->adjvex].data)

if(G.kind == DN) // 网

printf(":%d ", *(p->info))

}

else // 无向(避免输出两次)

{

if(i <p->adjvex)

{

printf("%s-%s ",G.vertices[i].data,

G.vertices[p->adjvex].data)

if(G.kind == AN) // 网

printf(":%d ",*(p->info))

}

}

p=p->nextarc

}

printf("\n")

}

}

// 求顶点的入度,算法7.12、7.13调用

void FindInDegree(ALGraph G,int indegree[])

{

int i

ArcNode *p

for(i=0i<G.vexnumi++)

indegree[i]=0// 赋初值

for(i=0i<G.vexnumi++)

{

p=G.vertices[i].firstarc

while(p)

{

indegree[p->adjvex]++

p=p->nextarc

}

}

}

typedef int SElemType// 栈类型

#define STACK_INIT_SIZE 10 // 存储空间初始分配量

#define STACKINCREMENT 2 // 存储空间分配增量

// 栈的顺序存储表示 P46

typedef struct SqStack

{

SElemType *base // 在栈构造之前和销毁之后,base的值为NULL

SElemType *top // 栈顶指针

int stacksize // 当前已分配的存储空间,以元素为单位

}SqStack // 顺序栈

// 构造一个空栈S。

int InitStack(SqStack *S)

{

// 为栈底分配一个指定大小的存储空间

(*S).base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType))

if( !(*S).base )

exit(0) // 存储分配失败

(*S).top = (*S).base // 栈底与栈顶相同表示一个空栈

(*S).stacksize = STACK_INIT_SIZE

return 1

}

// 若栈S为空栈(栈顶与栈底相同的),则返回1,否则返回0。

int StackEmpty(SqStack S)

{

if(S.top == S.base)

return 1

else

return 0

}

// 插入元素e为新的栈顶元素。

int Push(SqStack *S, SElemType e)

{

if((*S).top - (*S).base >= (*S).stacksize) // 栈满,追加存储空间

{

(*S).base = (SElemType *)realloc((*S).base,

((*S).stacksize + STACKINCREMENT) * sizeof(SElemType))

if( !(*S).base )

exit(0)// 存储分配失败

(*S).top = (*S).base+(*S).stacksize

(*S).stacksize += STACKINCREMENT

}

*((*S).top)++=e

// 这个等式的++ * 优先级相同,但是它们的运算方式,是自右向左

return 1

}

// 若栈不空,则删除S的栈顶元素,用e返回其值,并返回1;否则返回0。

int Pop(SqStack *S,SElemType *e)

{

if((*S).top == (*S).base)

return 0

*e = *--(*S).top

// 这个等式的++ * 优先级相同,但是它们的运算方式,是自右向左

return 1

}

// 算法7.12 P182

// 有向图G采用邻接表存储结构。若G无回路,则输出G的顶点的一个拓扑序

// 列并返回1, 否则返回0。

int TopologicalSort(ALGraph G)

{

int i,k,count,indegree[MAX_VERTEX_NUM]

SqStack S

ArcNode *p

FindInDegree(G,indegree)// 对各顶点求入度indegree[0..vernum-1]

InitStack(&S)// 初始化栈

for(i=0i<G.vexnum++i) // 建零入度顶点栈S

if(!indegree[i])

Push(&S,i)// 入度为0者进栈

count=0// 对输出顶点计数

while(!StackEmpty(S))

{

// 栈不空

Pop(&S,&i)

printf("%s ",G.vertices[i].data)// 输出i号顶点并计数

++count

for(p=G.vertices[i].firstarcpp=p->nextarc)

{

// 对i号顶点的每个邻接点的入度减1

k=p->adjvex

if(!(--indegree[k])) // 若入度减为0,则入栈

Push(&S,k)

}

}

if(count<G.vexnum)

{

printf("此有向图有回路\n")

return 0

}

else

{

printf("为一个拓扑序列。\n")

return 1

}

}

int main()

{

ALGraph f

printf("请选择有向图\n")

CreateGraph(&f)

Display(f)

TopologicalSort(f)

system("pause")

return 0

}

/*

输出效果:

请选择有向图

请输入图的类型(有向图:0,有向网:1,无向图:2,无向网:3): 0

请输入图的顶点数和边数:(空格)

4 4

请输入4个顶点的值(<3个字符):

a

b

c

d

请顺序输入每条弧(边)的弧尾和弧头(以空格作为间隔):

a b

a c

b d

c d

有向图

4个顶点:

a b c d

4条弧(边):

a→c a→b

b→d

c→d

a b c d 为一个拓扑序列。

请按任意键继续. . .

*/

#include<stdio.h>

#include<stdlib.h>

#define infinity 100 //权最羡滑肆大值定为100,相当于正无穷

#define max 3//让袭最大顶点数3个

typedef struct ArcCell{

int weight //权值

}ArcCell,AdjMatrix[max][max]

typedef struct{ //图

char vexs[max]

AdjMatrix arcx

int vexnum,arcnum

}MGrap

void CreateUDN(MGrap &G)

int main(){

MGrap G

CreateUDN(G)

return 0

}

void CreateUDN(MGrap &G)

{

int i,j,k

printf("Input the number of vex and arc:") //分别输入顶点和弧的个数

scanf("%d %d",&G.vexnum,&G.arcnum)

for(i=0i<G.vexnumi++) //依次输入每个顶点

{

printf("请输入第%d个顶点",i+1)

scanf("%c",&G.vexs[i])

}

for(i=0i<G.vexnumi++)

for(j=0j<G.vexnumj++)

G.arcx[i][j].weight = infinity

for(i=0i<G.arcnumi++)

{

printf("兄轿请输入弧的两端点:(NO.%d)",i+1) //输入第i+1条弧的两端点,确定弧

scanf("%d %d ",&k,&j )

scanf("%d",&G.arcx[k][j].weight)

G.arcx[j][k]=G.arcx[k][j] //无向图弧关于对角线对称

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/12542441.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2025-08-26
下一篇2025-08-26

发表评论

登录后才能评论

评论列表(0条)

    保存