void BFSTraverse(MGraph G, Status(*Visit)(VertexType)) {/* 初始条件: 图G存在,Visit是顶点的应用函数。算法7.6 */ /* 操作结果: 从第1个顶点起,按广度优先非递归遍历图G,并对每个顶点调用函数 */ /* Visit一次且仅一次。一旦Visit()失败,则操作失败。 */ /* 使用辅助队列Q和访问标志数组visited */ int u, v, w; VertexType w1, u1; SqQueue Q; for (v = 0; v < G.vexnum; v++) visited[v] = FALSE; //访问标志数组初始化(未被访问) InitQueue(Q); for (v = 0; v < G.vexnum; v++) { if (!visited[v]) { visited[v] = TRUE; Visit(G.vexs[v]); EnQueue(Q, v); while (!QueueEmpty(Q)) { DeQueue(Q, u); //队头元素出队并置为u strcpy(u1, GetVex(G, u)); for (w = FirstAdjVex(G, u1); w != -1; w = NextAdjVex(G, u1, strcpy(w1, GetVex(G, w)))) if (!visited[w]) { // w为u的尚未访问的邻接顶点的序号 visited[w] = TRUE; Visit(G.vexs[w]); EnQueue(Q, w); } } } } }
void DFSTree(ALGraph G,int v,CSTree &T) { // 从第v个顶点出发深度优先遍历图G,建立以T为根的生成树。算法7.8 Boolean first=TRUE; int w; CSTree p,q; VertexType v1,w1; visited[v]=TRUE; strcpy(v1,GetVex(G,v)); for(w=FirstAdjVex(G,v1);w>=0;w=NextAdjVex(G,v1,strcpy(w1,GetVex(G,w)))) // w依次为v的邻接顶点 if(!visited[w]) // w顶点不曾被访问 { p=(CSTree)malloc(sizeof(CSNode)); // 分配孩子结点 strcpy(p->data,GetVex(G,w)); p->firstchild=NULL; p->nextsibling=NULL; if(first) { // w是v的第一个未被访问的邻接顶点 T->firstchild=p; first=FALSE; // 是根的第一个孩子结点 } else // w是v的其它未被访问的邻接顶点 q->nextsibling=p; // 是上一邻接顶点的兄弟姐妹结点 q=p; DFSTree(G,w,q); // 从第w个顶点出发深度优先遍历图G,建立子生成树q } }
void BFSTraverse(OLGraph G,Status(*Visit)(VertexType)) { /* 初始条件: 有向图G存在,Visit是顶点的应用函数。算法7.6 */ /* 操作结果: 从第1个顶点起,按广度优先非递归遍历有向图G,并对每个顶点调用 */ /* 函数Visit一次且仅一次。一旦Visit()失败,则操作失败。 */ /* 使用辅助队列Q和访问标志数组visited */ int v,u,w; VertexType u1,w1; SqQueue Q; for(v=0;v<G.vexnum;v++) visited[v]=FALSE; InitQueue(&Q); for(v=0;v<G.vexnum;v++) if(!visited[v]) { visited[v]=TRUE; Visit(G.xlist[v].data); EnQueue(&Q,v); while(!QueueEmpty(Q)) { DeQueue(&Q,&u); strcpy(u1,*GetVex(G,u)); for(w=FirstAdjVex(G,u1);w>=0;w=NextAdjVex(G,u1,strcpy(w1,*GetVex(G,w)))) if(!visited[w]) /* w为u的尚未访问的邻接顶点的序号 */ { visited[w]=TRUE; Visit(G.xlist[w].data); EnQueue(&Q,w); } } } printf("\n"); }
void BFSTraverse(ALGraph G,void(*Visit)(char*)) {/*按广度优先非递归遍历图G。使用辅助队列Q和访问标志数组visited。*/ int v,u,w; VertexType u1,w1; LinkQueue Q; for(v=0;v<G.vexnum;++v) visited[v]=FALSE; /* 置初值 */ InitQueue(&Q); /* 置空的辅助队列Q */ for(v=0;v<G.vexnum;v++) /* 如果是连通图,只v=0就遍历全图 */ if(!visited[v]) /* v尚未访问 */ { visited[v]=TRUE; Visit(G.vertices[v].data); EnQueue(&Q,v); /* v入队列 */ while(!QueueEmpty(Q)) /* 队列不空 */ { DeQueue(&Q,&u); /* 队头元素出队并置为u */ strcpy(u1,*GetVex(G,u)); for(w=FirstAdjVex(G,u1);w>=0;w=NextAdjVex(G,u1,strcpy(w1,*GetVex(G,w)))) if(!visited[w]) /* w为u的尚未访问的邻接顶点 */ { visited[w]=TRUE; Visit(G.vertices[w].data); EnQueue(&Q,w); /* w入队 */ } } } printf("\n"); }
void DFSTree(ALGraph G,int v,CSTree *T) { /* 从第v个顶点出发深度优先遍历图G,建立以T为根的生成树。算法7.8 */ Boolean first=TRUE; int w; CSTree p,q; VertexType v1,w1; visited[v]=TRUE; strcpy(v1,*GetVex(G,v)); for(w=FirstAdjVex(G,v1);w>=0;w=NextAdjVex(G,v1,strcpy(w1,*GetVex(G,w)))) /* w依次为v的邻接顶点 */ if(!visited[w]) /* w顶点不曾被访问 */ { p=(CSTree)malloc(sizeof(CSNode)); /* 分配孩子结点 */ strcpy(p->data,*GetVex(G,w)); p->firstchild=NULL; p->nextsibling=NULL; if(first) { /* w是v的第一个未被访问的邻接顶点 */ (*T)->firstchild=p; first=FALSE; /* 是根的第一个孩子结点 */ } else /* w是v的其它未被访问的邻接顶点 */ q->nextsibling=p; /* 是上一邻接顶点的兄弟姐妹结点 */ q=p; DFSTree(G,w,&q); /* 从第w个顶点出发深度优先遍历图G,建立子生成树q */ } }
void BFSTraverse(AMLGraph G,Status(*Visit)(VertexType)) { /* 初始条件: 图G存在,Visit是顶点的应用函数。*/ /* 操作结果: 从第1个顶点起,按广度优先非递归遍历图G,并对每个顶点调用函数 */ /* Visit一次且仅一次。一旦Visit()失败,则操作失败。 */ /* 使用辅助队列Q和访问标志数组visite */ int v,u,w; VertexType w1,u1; LinkQueue Q; for(v=0;v<G.vexnum;v++) visite[v]=FALSE; /* 置初值 */ InitQueue(&Q); /* 置空的辅助队列Q */ for(v=0;v<G.vexnum;v++) if(!visite[v]) /* v尚未访问 */ { visite[v]=TRUE; /* 设置访问标志为TRUE(已访问) */ Visit(G.adjmulist[v].data); EnQueue(&Q,v); /* v入队列 */ while(!QueueEmpty(Q)) /* 队列不空 */ { DeQueue(&Q,&u); /* 队头元素出队并置为u */ strcpy(u1,*GetVex(G,u)); for(w=FirstAdjVex(G,u1);w>=0;w=NextAdjVex(G,u1,strcpy(w1,*GetVex(G,w)))) if(!visite[w]) /* w为u的尚未访问的邻接顶点的序号 */ { visite[w]=TRUE; Visit(G.adjmulist[w].data); EnQueue(&Q,w); } } } printf("\n"); }
/* 若w是v的最后一个邻接点,则返回-1 */ ArcNode *p; int v1,w1; v1=LocateVex(G,v); /* v1为顶点v在图G中的序号 */ w1=LocateVex(G,w); /* w1为顶点w在图G中的序号 */ p=G.vertices[v1].firstarc; while(p&&p->adjvex!=w1) /* 指针p不空且所指表结点不是w */ p=p->nextarc; if(!p||!p->nextarc) /* 没找到w或w是最后一个邻接点 */ return -1; else /* p->adjvex==w */ return p->nextarc->adjvex; /* 返回v的(相对于w的)下一个邻接顶点的序号 */ } Boolean visited[MAX_VERTEX_NUM]; /* 访问标志数组(全局量) */ void(*VisitFunc)(char* v); /* 函数变量(全局量) */ void DFS(ALGraph G,int v) { /* 从第v个顶点出发递归地深度优先遍历图G。*/ int w; VertexType v1,w1; strcpy(v1,*GetVex(G,v)); visited[v]=TRUE; /* 设置访问标志为TRUE(已访问) */ VisitFunc(G.vertices[v].data); /* 访问第v个顶点 */ for(w=FirstAdjVex(G,v1);w>=0;w=NextAdjVex(G,v1,strcpy(w1,*GetVex(G,w)))) if(!visited[w]) DFS(G,w); /* 对v的尚未访问的邻接点w递归调用DFS */ }
void DFS(MGraph G, int v) {/* 从第v个顶点出发递归地深度优先遍历图G。算法7.5 */ VertexType w1, v1; int w; visited[v] = TRUE; /* 设置访问标志为TRUE(已访问) */ VisitFunc(G.vexs[v]); //访问第v个顶点 strcpy(v1, GetVex(G, v)); for (w = FirstAdjVex(G, v1); w != -1; w = NextAdjVex(G, v1, strcpy(w1, GetVex(G, w)))) if (!visited[w]) DFS(G, w); //对v的尚未访问的序号为w的邻接顶点递归调用DFS }
/** * 算法7.7,建立无向图G的深度优先生成森林的孩子兄弟链表 */ Status DFSForst(ALGraph G, CSTree &T, bool visited[]) { int v; CSTree p, q; T = NULL; for (v = 0; v < G.vexnum; v++) { visited[v] = false; } for (v=0; v < G.vexnum; v++) { if (!visited[v]) { p = (CSTree) malloc (sizeof(CSNode)); if (!p) return ERROR; p->data = GetVex(G, v); p->lchild = NULL; p->nextsibling = NULL; if (!T) { //是第一棵生成树的根 T = p; } else { q->nextsibling = p; } q = p; DFSTree(G, v, p, visited); } } return OK; }
/** * 算法7.8,从第v个顶点出发深度优先遍历图G,建立以T为根的生成树 */ Status DFSTree(ALGraph G, int v, CSTree T, bool visited[]) { bool first; CSTree p, q; int w; visited[v] = true; first = true; for (w = FirstAdjVex(G, v); w >= 0; w = NextAdjVex(G, v, w)) { if (!visited[w]) { p = (CSTree) malloc (sizeof(CSNode)); //分配孩子结点 if (!p) { return ERROR; } p->data = GetVex(G, w); p->lchild = NULL; p->nextsibling = NULL; if (first) { T->lchild = p; first = false; } else { q->nextsibling = p; } q = p; DFSTree(G, w, q, visited); } } return OK; }
void DFSForest(ALGraph G, CSTree &T) { // 建立无向图G的深度优先生成森林的(最左)孩子(右)兄弟链表T。算法7.7 CSTree p, q; //孩子兄弟树p、q int v; T = NULL; for (v=0; v<G.vexnum; ++v) visited[v] = FALSE; // 赋初值 for (v=0; v<G.vexnum; ++v) // 从第0个顶点找起 if (!visited[v]) // 第v个顶点不曾被访问 { // 第v顶点为新的生成树的根结点 p = (CSTree) malloc(sizeof (CSNode)); // 分配根结点 p->data=GetVex(G, v); //当前顶点(第v个)拷贝到新分配的根结点 p->firstchild = NULL; p->nextsibling = NULL; if (!T) // 如果孩子兄弟树T为空,表示是第一棵生成树的根(T的根) T = p; //所以T取新分配的根结点 else // 如果孩子兄弟树T不为空,表示是其它生成树的根(前一棵的根的“兄弟”) q->nextsibling = p; //令前一棵的根的“兄弟”取新分配的根结点 q = p; // q取当前生成树的根 DFSTree(G, v, p); // 从第v顶点出发建立以p为根的生成树 } }
//Function use: 从第1个顶点起广度非递归遍历图,并对每个顶点 //调用函数,一旦Visit()失败,则失败 void BFSTraverse(MGraph G, Status (*Visit)(VertexType)) { int nSeqV; int nSeqW; int nSeqU; VertexType u; VertexType w; LinkQueue Q; for (nSeqV = 0; nSeqV < G.vexnum; nSeqV++) { visited[nSeqV] = FALSE; } InitQueue(&Q); for (nSeqV = 0; nSeqV < G.vexnum; nSeqV++) { if (!visited[nSeqV]) { visited[nSeqV] = TRUE; Visit(G.vexs[nSeqV]); EnQueue(&Q, nSeqV); while (!QUEUEEMPTY(Q)) { DeQueue(&Q, &nSeqU); strcpy(u, *GetVex(G, nSeqU)); for (nSeqW = FirstAdjVex(G, u);\ nSeqW >= 0;\ nSeqW = NextAdjVex(G, u, strcpy(w, *GetVex(G, nSeqW)))) { visited[nSeqW] = TRUE; Visit(G.vexs[nSeqW]); EnQueue(&Q, nSeqW); } } } } printf("\n"); }
void DFSTree(ALGraph G, int v, CSTree &T) { // 从第v个顶点出发深度优先遍历图G,建立以T为根的生成树。算法7.8 Boolean first = TRUE; int w; CSTree p, q; //孩子兄弟树p、q VertexType v1, w1; visited[v] = TRUE; v1=GetVex(G, v); //顶点v1序号为v // w依次为v的邻接顶点 //w初始化为v1第一个邻接点序号 //只要w大于等于0,就执行循环体 //循环体完毕,w取v1的(相对于w1(序号w)的)下一个邻接顶点的序号,准备下轮循环 for (w=FirstAdjVex(G,v1); w>=0; w=NextAdjVex(G,v1,w1=GetVex(G,w))) if (!visited[w]) // w顶点不曾被访问 { p = (CSTree) malloc(sizeof (CSNode)); // 分配新孩子结点 p->data=GetVex(G, w); //v的当前邻接顶点复制到新结点 p->firstchild = NULL; p->nextsibling = NULL; if (first) // w是v的第一个未被访问的邻接顶点 { T->firstchild = p; //树T的长子取新结点 first = FALSE; // 长子标志置假 } else // w是v的其它未被访问的邻接顶点,是上一邻接顶点的兄弟结点 q->nextsibling = p; // 上一邻接顶点的兄弟结点取新结点 q = p; //q取新结点 DFSTree(G, w, q); // 从第w个顶点出发深度优先遍历图G,递归建立以q为根的子生成树 } }
//Function use: 从第nSeqV个顶点出发深度遍历图 void DFS(MGraph G, int nSeqV) { VertexType v; VertexType w; int nSeqW; visited[nSeqV] = TRUE; VisitFunc(G.vexs[nSeqV]); strcpy(v, *GetVex(G, nSeqV)); for (nSeqW = FirstAdjVex(G, v);\ nSeqW >= 0; nSeqW = NextAdjVex(G, v, w)) { if (!visited[nSeqW]) { DFS(G, nSeqW); } } }
void Display(MGraph G) { int i, j; char s[7] = "无向网", s1[3] = "边"; switch (G.kind) { case DG: strcpy(s, "有向图"); strcpy(s1, "弧"); break; case DN: strcpy(s, "有向网"); strcpy(s1, "弧"); break; case UDG: strcpy(s, "无向图"); case UDN:; } printf("%d个顶点%d条%s的%s。顶点依次是:", G.vexnum, G.arcnum, s1, s); for (i = 0; i < G.vexnum; ++i) Visit(GetVex(G, i)); printf("\nG.arcs.adj:\n"); for (i = 0; i < G.vexnum; i++) { for (j = 0; j < G.vexnum; j++) printf("%11d", G.arcs[i][j].adj); printf("\n"); } printf("G.arcs.info:\n"); if (G.kind < 2) printf(" 弧尾 弧头 该%s的信息:\n", s1); else printf("顶点1 顶点2 该%s的信息:\n", s1); for (i = 0; i < G.vexnum; i++) if (G.kind < 2) { for (j = 0; j < G.vexnum; j++) if (G.arcs[i][j].info) { printf("%5s %5s ", G.vexs[i].name, G.vexs[j].name); OutputArc(G.arcs[i][j].info); } } else { for (j = i + 1; j < G.vexnum; j++) if (G.arcs[i][j].info) { printf("%5s %5s ", G.vexs[i].name, G.vexs[j].name); OutputArc(G.arcs[i][j].info); } } }
void DFSForest(ALGraph G,CSTree *T) { /* 建立无向图G的深度优先生成森林的(最左)孩子(右)兄弟链表T。算法7.7 */ CSTree p,q; int v; *T=NULL; for(v=0;v<G.vexnum;++v) visited[v]=FALSE; /* 赋初值 */ for(v=0;v<G.vexnum;++v) /* 从第0个顶点找起 */ if(!visited[v]) { /* 第v顶点为新的生成树的根结点 */ p=(CSTree)malloc(sizeof(CSNode)); /* 分配根结点 */ strcpy(p->data,*GetVex(G,v)); p->firstchild=NULL; p->nextsibling=NULL; if(!*T) /* 是第一棵生成树的根(T的根) */ *T=p; else /* 是其它生成树的根(前一棵的根的"兄弟") */ q->nextsibling=p; q=p; /* q指示当前生成树的根 */ DFSTree(G,v,&p); /* 建立以p为根的生成树 */ } }
void DFSForest(Graph G, CSTree &T) { CSTree p, q; int v; T = NULL; for (v = 0; v < G.vexnum; ++v) visited[v] = FALSE; for (v = 0; v < G.vexnum; ++v) if (!visited[v]) { p = (CSTree)malloc(sizeof(CSNode)); p->data = GetVex(G, v); p->firstchild = NULL; p->nextsibling = NULL; if (!T) T = p; else q->nextsibling = p; q = p; DFSTree(G, v, p); } }
void DFSForest(ALGraph G,CSTree &T) { // 建立无向图G的深度优先生成森林的(最左)孩子(右)兄弟链表T。算法7.7 CSTree p,q; int v; T=NULL; for(v=0;v<G.vexnum;++v) visited[v]=FALSE; // 赋初值 for(v=0;v<G.vexnum;++v) // 从第0个顶点找起 if(!visited[v]) // 第v个顶点不曾被访问 { // 第v顶点为新的生成树的根结点 p=(CSTree)malloc(sizeof(CSNode)); // 分配根结点 strcpy(p->data,GetVex(G,v)); p->firstchild=NULL; p->nextsibling=NULL; if(!T) // 是第一棵生成树的根(T的根) T=p; else // 是其它生成树的根(前一棵的根的"兄弟") q->nextsibling=p; q=p; // q指示当前生成树的根 DFSTree(G,v,p); // 建立以p为根的生成树 } }
Status DeleteVex(AMLGraph *G,VertexType v) { /* 初始条件: 无向图G存在,v是G中某个顶点 */ /* 操作结果: 删除G中顶点v及其相关的边 */ int i,j; VertexType w; EBox *p; i=LocateVex(*G,v); /* i为待删除顶点的序号 */ if(i<0) return ERROR; for(j=0;j<(*G).vexnum;j++) /* 删除与顶点v相连的边(如果有的话) */ { if(j==i) continue; strcpy(w,*GetVex(*G,j)); /* w是第j个顶点的值 */ DeleteArc(G,v,w); } for(j=i+1;j<(*G).vexnum;j++) /* 排在顶点v后面的顶点的序号减1 */ (*G).adjmulist[j-1]=(*G).adjmulist[j]; (*G).vexnum--; /* 顶点数减1 */ for(j=i;j<(*G).vexnum;j++) /* 修改顶点的序号 */ { p=(*G).adjmulist[j].firstedge; if(p) { if(p->ivex==j+1) { p->ivex--; p=p->ilink; } else { p->jvex--; p=p->jlink; } } } return OK; }
void DFSTree(Graph G, int v, CSTree &T) { Boolean first = TRUE; int w; CSTree p, q; visited[v] = TRUE; for (w = FirstAdjVex(G, v); w >= 0; w = NextAdjVex(G, v, w)) if (!visited[w]) { p = (CSTree)malloc(sizeof(CSNode)); p->data = GetVex(G, w); p->firstchild = NULL; p->nextsibling = NULL; if (first) { T->firstchild = p; first = FALSE; } else { q->nextsibling = p; } q = p; DFSTree(G, w, q); } }