1、typedef int QElemType; / 队列类型 / 单链队列队列的链式存储结构 typedef struct QNode QElemType data; /数据域 struct QNode *next; /指针域QNode,*QueuePtr; QueuePtr front, /队头指针,指针域指向队头元素 rear; /队尾指针,指向队尾元素LinkQueue;/ 若G中存在顶点u,则返回该顶点在图中位置;否则返回-1。 int LocateVex(ALGraph G,VertexType u) int i; for(i=0;iG.vexnum;+i) if(strcmp(u,G
2、.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(请输入图的类型(有向图:0,有向网:1,无向图:2,无向网:3): ); scanf(%d,&(*G).kind);请输入图的顶点数和边数:(空格)n%d%d, &(*G).vexnum, &(*G).arcnum);请输入%d个顶点的值(%d个字符):n,(*G).ve
3、xnum,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(请顺序输入每条弧(边)的权值、弧尾和弧头(以空格作为间隔): else / 图 请顺序输入每条弧(边)的弧尾和弧头(以空格作为间隔): for(k = 0;k adjvex = j; if(*G).kind = 1 | (*G).kind = 3) / 网 p-info =
4、 (int *)malloc(sizeof(int); *(p-info) = w; elseinfo = NULL; / 图 nextarc = (*G).verticesi.firstarc; / 插在表头 (*G).verticesi.firstarc = p; if(*G).kind = 2) / 无向图或网,产生第二个表结点 p = (ArcNode*)malloc(sizeof(ArcNode);adjvex = i; if(*G).kind = 3) / 无向网 p-info = (int*)malloc(sizeof(int); *(p- else / 无向图 nextarc
5、= (*G).verticesj.firstarc; (*G).verticesj.firstarc = p; return 1;/ 销毁图G。void DestroyGraph(ALGraph *G) ArcNode *p,*q;i nextarc; if(*G).kind%2) / 网 free(p-info); free(p); p=q; (*G).vexnum=0; (*G).arcnum=0;/ 返回v的值。VertexType* GetVex(ALGraph G,int v) if(v=G.vexnum|v -1) / v是G的顶点 strcpy(*G).verticesi.dat
6、a,value); return 1; return 0;/ 返回v的第一个邻接顶点的序号。若顶点在G中没有邻接顶点,则返回-1。int FirstAdjVex(ALGraph G,VertexType v) int v1; v1 = LocateVex(G,v); / v1为顶点v在图G中的序号 p = G.verticesv1.firstarc; if(p) return p-adjvex; else return -1;/ 返回v的(相对于w的)下一个邻接顶点的序号。若w是v的最后一个/ 邻接点, 则返回-1。int NextAdjVex(ALGraph G,VertexType v,V
7、ertexType w) int v1,w1; w1 = LocateVex(G,w); / w1为顶点w在图G中的序号 while(p&p-adjvex != w1) / 指针p不空且所指表结点不是w p = p- if(!p|!nextarc) / 没找到w或w是最后一个邻接点 else / p-adjvex=w / 返回v的(相对于w的)下一个邻接顶点的序号 nextarc-/ 在图G中增添新顶点v(不增添与顶点相关的弧,留待InsertArc()去做)。void InsertVex(ALGraph *G,VertexType v) strcpy(*G).vertices(*G).vex
8、num.data,v); / 构造新顶点向量 (*G).vertices(*G).vexnum.firstarc=NULL; (*G).vexnum+; / 图G的顶点数加1 / 删除G中顶点v及其相关的弧。int DeleteVex(ALGraph *G,VertexType v) int i,j; j=LocateVex(*G,v); / j是顶点v的序号 if(j free(q); (*G).arcnum-; / 弧或边数减1 (*G).vexnum-; / 顶点数减1 for(i = j; i+) / 顶点v后面的顶点前移 (*G).verticesi = (*G).verticesi
9、+1; / 删除以v为入度的弧或边且必要时修改表结点的顶点位置值 i+) / 指向第1条弧或边 while(p) / 有弧 if(p-adjvex = j) / 是以v为入度的边。 if(p = (*G).verticesi.firstarc) / 待删结点是第1个结点 (*G).verticesi.firstarc = p- if(*G).kind % 2) / 网 free(p- free(p); p = (*G).verticesi.firstarc; if(*G).kind nextarc = p- if(*G).kind%2) / 网 p = q- if(p-adjvex j) p-
10、adjvex-; / 修改表结点的顶点位置值(序号) q = p; p = p-/ 在G中增添弧,若G是无向的,则还增添对称弧。int InsertArc(ALGraph *G,VertexType v, VertexType w) int w1,i,j; / 弧尾或边的序号 j=LocateVex(*G,w); / 弧头或边的序号 if(i 0 | j adjvex=j;info=(int*)malloc(sizeof(int); *(p-info)=w1; (*G).verticesi.firstarc = p; if(*G).kind = 2) / 无向,生成另一个表结点 if(*G).
11、kind = 3) / 无向网 info) = w1;info=NULL;nextarc=(*G).verticesj.firstarc; (*G).verticesj.firstarc=p;/ 在G中删除弧,若G是无向的,则还删除对称弧int DeleteArc(ALGraph *G,VertexType v,VertexType w) i = LocateVex(*G,v); / i是顶点v(弧尾)的序号 j = LocateVex(*G,w); / j是顶点w(弧头)的序号 0 | i = j) p=(*G).verticesi.firstarc; / p指向顶点v的第一条出弧 adjv
12、ex!=j) / p不空且所指之弧不是待删除弧 if(p&adjvex=j) / 找到弧 / 指向下一条弧 q-nextarc=p- if(*G).kind%2) / 网 free(p- free(p); / 释放此结点 if(*G).kind=2) / 无向,删除对称弧 p=(*G).verticesj.firstarc; / p指隙鉾的第一条出弧 while(p&=i) / p不空且所指之弧不是待删除弧 if(p&adjvex=i) / 找到弧 q- if(*G).kind=3) / 无向网 int visitedMAX_VERTEX_NUM; / 访问标志数组(全局量) void(*Vi
13、sitFunc)(char* v); / 函数变量(全局量) / 算法7.5 P169/ 从第v个顶点出发递归地深度优先遍历图G。void DFS(ALGraph G,int v) VertexType v1,w1; strcpy(v1,*GetVex(G,v); visitedv = 1; / 设置访问标志为1(已访问) VisitFunc(G.verticesv.data); / 访问第v个顶点 for(w = FirstAdjVex(G,v1); w = 0; w = NextAdjVex(G,v1,strcpy(w1,*GetVex(G,w) if(!visitedw) DFS(G,w
14、); / 对v的尚未访问的邻接点w递归调用DFS / 算法7.4 P169/ 对图G作深度优先遍历。void DFSTraverse(ALGraph G,void(*Visit)(char*) int v; / 使用全局变量VisitFunc,使DFS不必设函数指针参数 VisitFunc = Visit; for(v = 0; v next = NULL; /队头指针指向空,无数据域,这样构成了一个空队列/ 插入元素e为Q的新的队尾元素。int EnQueue(LinkQueue *Q, QElemType e) QueuePtr p = (QueuePtr)malloc(sizeof(QN
15、ode); if( !p ) / 存储分配失败 / 生成一个以为e为数据域的队列元素data = e; /将该新队列元素接在队尾的后面 (*Q).rear-next = p; (*Q).rear = p;/ 若队列不空,删除Q的队头元素,用e返回其值,并返回1,否则返回0。int DeQueue(LinkQueue *Q,QElemType *e) QueuePtr p; if(*Q).front=(*Q).rear) p=(*Q).front-next; /队头元素 *e=p-data;next=p- if(*Q).rear=p) (*Q).rear=(*Q).front; free(p);
16、/ 若Q为空队列,则返回1,否则返回0。int QueueEmpty(LinkQueue Q) if(Q.front = Q.rear)/ 算法7.6 P170/ 按广度优先非递归遍历图G。使用辅助队列Q和访问标志数组visited。void BFSTraverse(ALGraph G,void(*Visit)(char*) int v,u,w; VertexType u1,w1; LinkQueue Q; +v) visitedv=0; / 置初值 InitQueue(&Q); / 置空的辅助队列Q v+) / 如果是连通图,只v=0就遍历全图 visitedv) / v尚未访问 visitedv=1; Visit(G.verticesv.data); EnQueue(&Q,v); / v入队列 while(!QueueEmpty(Q) / 队列不空 DeQueue(&Q,&u); / 队头元素出队并置为u strcpy(u1,*GetVex(G,u); for(w = FirstAdjVex(G,u1); w = NextAdjVex(G, u1, strcpy(w1, *GetVex(G,w) if(!visitedw) / w为u的尚未访问的邻接顶点 visited
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1