数据结构之无向图邻接表DFS之查询遍历关节点

来源:互联网 发布:天天模拟器官网mac 编辑:程序博客网 时间:2024/06/05 16:34
#include<iostream>using namespace std;#define MAXVEX 100typedef char VType;typedef struct ArcNode{int adjvex;ArcNode *pNextArc;}ArcNode;typedef struct VexNode{VType data;ArcNode *pFirstArc;}VexNode;typedef struct{VexNode VLnode[MAXVEX];int Vnums;int Anums;}ALGraph;void CreateGraph(ALGraph &G){int i, j, k;ArcNode *pA;cin >> G.Vnums >> G.Anums;for (i = 0; i < G.Vnums; ++i){cin >> G.VLnode[i].data;G.VLnode[i].pFirstArc = NULL;}for (k = 0; k < G.Anums; ++k){cin >> i >> j;pA = new ArcNode;pA->adjvex = i;pA->pNextArc = G.VLnode[j].pFirstArc;G.VLnode[j].pFirstArc = pA;pA = new ArcNode;pA->adjvex = j;pA->pNextArc = G.VLnode[i].pFirstArc;G.VLnode[i].pFirstArc = pA;}}void DestroyGraph(ALGraph &G){int i;ArcNode *p, *q;for (i = 0; i < G.Vnums; ++i){p = G.VLnode[i].pFirstArc;while (p){q = p->pNextArc;delete p;p = q;}}G.Anums = 0;}int LocateVex(ALGraph G, VexNode v){int i;for (i = 0; i < G.Vnums; ++i)if (G.VLnode[i].data = v.data)return i;return -1;}VType GetVex(ALGraph G, int i){if (i >= G.Vnums || i < 0)exit(-1);return G.VLnode[i].data;}bool PutVex(ALGraph &G, int i, VType value){i = LocateVex(G, G.VLnode[i]);if (i > -1){G.VLnode[i].data = value;return true;}elsereturn false;}int FirstAdjVex(ALGraph G, VexNode v){int i;ArcNode *pA;i = LocateVex(G, v);pA = G.VLnode[i].pFirstArc;if (pA)return pA->adjvex;elsereturn -1;}int NextAdjVex(ALGraph G, VexNode v, VexNode w){int i, j;ArcNode *pA;i = LocateVex(G, v);j = LocateVex(G, w);pA = G.VLnode[i].pFirstArc;while (pA&&pA->adjvex != j)pA = pA->pNextArc;if (!pA || !(pA->pNextArc))return -1;else{pA = pA->pNextArc;return pA->adjvex;}}void InsertVex(ALGraph &G, VexNode v){G.VLnode[G.Vnums].data = v.data;G.VLnode[G.Vnums].pFirstArc = NULL;G.Vnums++;}bool DeleteVex(ALGraph &G, VexNode v){int i, j;ArcNode *p, *q = NULL;j = LocateVex(G, v);if (j < 0)return false;p = G.VLnode[j].pFirstArc;while (p){q = p;p = p->pNextArc;delete q;G.Anums--;}G.Vnums--;for (i = j; i < G.Vnums; ++i){G.VLnode[i] = G.VLnode[i + 1];}for (i = 0; i < G.Vnums; ++i){p = G.VLnode[i].pFirstArc;while (p){if (p->adjvex == j){if (p == G.VLnode[i].pFirstArc){G.VLnode[i].pFirstArc = p->pNextArc;delete p;}else{q->pNextArc = p->pNextArc;delete p;p = q->pNextArc;}}else{if (p->adjvex>j)p->adjvex--;q = p;p = p->pNextArc;}}}return true;}bool InsertArc(ALGraph &G, VexNode v, VexNode w){ArcNode *pA;int i, j;i = LocateVex(G, v);j = LocateVex(G, w);if (i < 0 || j < 0)return false;G.Anums++;pA = new ArcNode;pA->adjvex = i;pA->pNextArc = G.VLnode[j].pFirstArc;G.VLnode[j].pFirstArc = pA;pA = new ArcNode;pA->adjvex = j;pA->pNextArc = G.VLnode[i].pFirstArc;G.VLnode[i].pFirstArc = pA;return true;}bool DeleteArc(ALGraph &G, VexNode v, VexNode w){ArcNode *p, *q = NULL;int i, j;i = LocateVex(G, v);j = LocateVex(G, w);p = G.VLnode[i].pFirstArc;while (p&&p->adjvex != j){q = p;p = p->pNextArc;}if (p&&p->adjvex == j){if (p == G.VLnode[i].pFirstArc)G.VLnode[i].pFirstArc = p->pNextArc;elseq->pNextArc = p->pNextArc;delete p;}p = G.VLnode[j].pFirstArc;while (p&&p->adjvex != i){q = p;p = p->pNextArc;}if (p&&p->adjvex == i){if (p == G.VLnode[j].pFirstArc)G.VLnode[j].pFirstArc = p->pNextArc;elseq->pNextArc = p->pNextArc;delete p;G.Anums--;}return true;}void VisitVex(VexNode v){cout << v.data << " ";}void VisitArc(VexNode v, VexNode w){cout << "(" << v.data << "->" << w.data << ")" << " ";}void PrintGraph(ALGraph G){int i;ArcNode *p;for (i = 0; i < G.Vnums; ++i)VisitVex(G.VLnode[i]);cout << endl;for (i = 0; i < G.Vnums; ++i){p = G.VLnode[i].pFirstArc;while (p){VisitArc(G.VLnode[i], G.VLnode[p->adjvex]);p = p->pNextArc;}}cout << endl;}bool VisitTag[MAXVEX];void DFS(ALGraph G, int i){ArcNode *p;VisitTag[i] = true;VisitVex(G.VLnode[i]);p = G.VLnode[i].pFirstArc;while (p){if (!VisitTag[p->adjvex])DFS(G, p->adjvex);p = p->pNextArc;}}void DFSEqual(ALGraph G, int i){int j;VisitTag[i] = true;VisitVex(G.VLnode[i]);for (j = FirstAdjVex(G, G.VLnode[i]); j >= 0; j = NextAdjVex(G, G.VLnode[i], G.VLnode[j]))if (!VisitTag[j])DFSEqual(G, j);}void DFST(ALGraph G){int i;for (i = 0; i < G.Vnums; ++i)VisitTag[i] = false;for (i = 0; i < G.Vnums; ++i)if (!VisitTag[i])DFSEqual(G, i);//or DFSEqual(G,i);cout << endl;}#define QSIZE MAXVEXtypedef struct Queue{int *pBase;int Front;int Rear;}Queue;void InitQueue(Queue &Q){Q.pBase = new int[QSIZE];Q.Front = 0;Q.Rear = 0;}bool QueueFull(Queue Q){if ((Q.Rear + 1) % QSIZE == Q.Front)return true;elsereturn false;}bool QueueEmpty(Queue Q){if (Q.Rear == Q.Front)return true;elsereturn false;}void EnQueue(Queue &Q, int i){if (QueueFull(Q))return;Q.pBase[Q.Rear] = i;Q.Rear = (Q.Rear + 1) % QSIZE;}void DeQueue(Queue &Q, int &i){if (QueueEmpty(Q))return;i = Q.pBase[Q.Front];Q.Front = (Q.Front + 1) % QSIZE;}void BFST(ALGraph G){Queue Q;int i, j;InitQueue(Q);for (i = 0; i < G.Vnums; ++i)VisitTag[i] = false;for (i = 0; i < G.Vnums; ++i){if (!VisitTag[i]){VisitTag[i] = true;VisitVex(G.VLnode[i]);EnQueue(Q, i);while (!QueueEmpty(Q)){DeQueue(Q, i);for (j = FirstAdjVex(G, G.VLnode[i]); j != -1; j = NextAdjVex(G, G.VLnode[i], G.VLnode[j])){if (!VisitTag[j]){VisitTag[j] = true;VisitVex(G.VLnode[j]);EnQueue(Q, j);}}}}}cout << endl;}//测试有错误void BFST1(ALGraph G){Queue Q;int i;ArcNode *p;InitQueue(Q);for (i = 0; i < G.Vnums; ++i)VisitTag[i] = false;for (i = 0; i < G.Vnums; ++i){if (!VisitTag[i]){VisitTag[i] = true;VisitVex(G.VLnode[i]);EnQueue(Q, i);while (!QueueEmpty(Q)){DeQueue(Q, i);p = G.VLnode[i].pFirstArc;while (p){if (!VisitTag[p->adjvex]){VisitTag[p->adjvex] = true;VisitVex(G.VLnode[p->adjvex]);}p = p->pNextArc;}}}}cout << endl;}int cnt;static int low[MAXVEX];int VisitOrder[MAXVEX];void VisitArticul(int i, VType value){cout << "(" << i << "," << value << ") ";}void DFSArticul(ALGraph G, int i){int j, min;ArcNode *p;VisitOrder[i] = ++cnt;min = VisitOrder[i];for (p = G.VLnode[i].pFirstArc; p; p = p->pNextArc){//对i位置顶点的各个邻接点进行深度优先搜索,则成功访问到的皆为生成树上i的后代结点j = p->adjvex;if (VisitOrder[j] == 0)//没有访问必做儿子{DFSArticul(G, j);//返回low[j](全局变量)if (low[j] < min)min = low[j];if (low[j] >= VisitOrder[i])VisitArticul(i, G.VLnode[i].data);//  关节点以访问来标记}else//否则必做祖先{if (VisitOrder[j] < min)//小于则替换min = VisitOrder[j];}}low[i] = min;}void FindArticul(ALGraph G)//必须是连通图{int i, j;ArcNode *p;cnt = 1;VisitOrder[0] = 1;// 设定邻接表上0号顶点为生成树的根(第一个访问的)low[0] =VisitOrder[0];for (i = 1; i < G.Vnums; ++i)VisitOrder[i] = 0; //其他暂未访问p = G.VLnode[0].pFirstArc;//从生成树根的第一个邻接点开始访问if (p)//为防止设置成非连通图而设定.如果是连通的话一定有邻接点,则if根本不需要{j = p->adjvex;//显然是生成树根节点在顶点序列中的位置,如果上一注释成立,则与p=G.VLnode[0].pFirstArc;直接衔接DFSArticul(G, j);//从第j顶点出发深度优先查找关节点if (cnt < G.Vnums)//生成树上的根有至少两棵子树VisitArticul(0, G.VLnode[0].data);while (p->pNextArc)//如果上一句成立且又是连通图,则while一定至少执行一次{p = p->pNextArc;j = p->adjvex;if (VisitOrder[j] == 0)//如果是连通图的话,if条件根本不需要.直接DFSArticul(G, j);DFSArticul(G, j);}}}int main(void){ALGraph G;CreateGraph(G);BFST1(G);DFST(G);PrintGraph(G);FindArticul(G);return(0);}

0 0
原创粉丝点击