#include<iostream>
using namespace std;
#define MAXVEX 100
typedef 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;
}
else
return 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;
else
return -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;
else
q->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;
else
q->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 MAXVEX
typedef 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;
else
return false;
}
bool QueueEmpty(Queue Q)
{
if (Q.Rear == Q.Front)
return true;
else
return 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(DGraph G)
{
Queue Q;
int i, j, k;
InitQueue(Q);
for (k = 0; k< G.Vnums; ++k)
VisitTag[k] = false;
for (k = 0; k < G.Vnums; ++k)
{
if (!VisitTag[k])
{
VisitTag[k] = true;
VisitVex(G.VLnode[k]);
EnQueue(Q, k);
while (!QueueEmpty(Q))
{
DeQueue(Q, i);
for (j = FirstAdjVex(G, G.VLnode[i]); j >= 0; 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 j)
{//由findArticul()函数调用
int k, min;
ArcNode *p;
VisitOrder[j] = ++cnt;
min = VisitOrder[j];
for (p = G.VLnode[j].pFirstArc; p; p = p->pNextArc)
{//对j位置顶点的各个邻接点进行深度优先搜索,则成功访问到的皆为生成树上j的后代结点
k = p->adjvex;
if (VisitOrder[k] == 0)//没有访问的邻接点必做j的儿子
{
DFSArticul(G, k);//对其没有访问过的邻接点进行递归调用
if (low[k] < min)
min = low[k];//更新min
if (low[k] >= VisitOrder[j])//关节点
VisitArticul(j, G.VLnode[j].data);// 访问关节点
}
else//已经访问过了的邻接点或为j的祖先或者是与j有回边相通
{
if (VisitOrder[k] < min)//小于则替换
min = VisitOrder[k];//更新min
}
}
low[j] = 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);//从第一个顶点(对应生成树的根结点)的第一个邻接点出发进行深度优先查找关节点
//调用之后完成生成树的根结点的一棵子树
if (cnt < G.Vnums)//生成树上的根有至少两棵子树,生成树的根结点为关节点
VisitArticul(0, G.VLnode[0].data);//访问关节点
while (p->pNextArc)//如果上一句(if语句)成立,则while一定至少执行一次;否则,则while语句一定不执行
{//对第一个顶点(生成树的根结点)的其他邻接点进行检查
p = p->pNextArc;
j = p->adjvex;
if (VisitOrder[j] == 0)
DFSArticul(G, j);
}
}
}
int main(void)
{
ALGraph G;
CreateGraph(G);
BFST1(G);
DFST(G);
PrintGraph(G);
FindArticul(G);
return(0);
}
数据结构之无向图邻接表DFS之查询遍历关节点(参考整理严蔚敏数据结构)
原文作者:数据结构之图
原文地址: https://blog.csdn.net/hgeternal/article/details/40507493
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/hgeternal/article/details/40507493
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。