您的位置:首页 > 理论基础 > 数据结构算法

数据结构之无向图邻接表DFS之创建打印生成森林(整理严蔚敏数据结构)

2014-10-27 12:25 471 查看
#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(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;
}

/*******************************************/
typedef VType ElemType;

typedef struct CSNode
{
ElemType data;
CSNode *pFchild;
CSNode *pNsibling;
}CSNode, *CSTree;

void DFSTree(ALGraph G, int i, CSTree &T)
{//从第i+1个顶点出发深度优先遍历图G,建立以T为根
//的生成树.
bool first = true;
int j;
CSTree p, q=NULL;
VisitTag[i] = true;
for (j = FirstAdjVex(G, G.VLnode[i]); j != -1; j = NextAdjVex(G, G.VLnode[i], G.VLnode[j]))
{
if (!VisitTag[j])
{
p = new CSNode;
p->data = GetVex(G,j);
p->pFchild = NULL;
p->pNsibling = NULL;
if (first)
{//根的第一个孩子
T->pFchild = p;
first = false;
}
else
q->pNsibling = p;
q = p;
DFSTree(G, j, q);
}
}
}

void DFSForest(ALGraph G, CSTree &T)
{//如果为连通图的话,则只建立一棵生成树
//如果为非连通图的话,则建立二叉树式的生成森林
//如果为树,则T指向该树的根结点;如果为森林,则T
//指向第一棵树的根结点
CSTree p;
CSTree q = NULL;//如果为连通图的话,不需要
int i;
T = NULL;
for (i = 0; i < G.Vnums; ++i)
VisitTag[i] = false;
for (i = 0; i < G.Vnums; ++i)
{//一次循环对应一棵生成.如果原先的为连通图,那么
//只进行一次循环,只生成一棵生成树.
if (!VisitTag[i])
{//如果是连通图的话,那么无需if,直接执行下面语句
p = new CSNode;
p->data = GetVex(G, i);
p->pFchild = NULL;
p->pNsibling = NULL;
if (!T)//第一棵生成树的根
T = p;
else//是其他生成树的根,当然势必有大于1棵树,势必为非连通图
q->pNsibling = p;
q = p;//q指示当前生成树的根,如果为连通图的话,则不需要该句
DFSTree(G, i, p);//建立以p为根的生成树
}
}
}

void Visit(CSTree T)
{
cout << T->data << " ";
}

void PreOrder(CSTree T)
{//树先根遍历(森林先序遍历)
if (T)
{
Visit(T);
PreOrder(T->pFchild);
PreOrder(T->pNsibling);
}
}

int main(void)
{
ALGraph G;
CSTree T;
CreateGraph(G);
DFST(G);//深度优先遍历图
DFSForest(G, T);//深度优先搜索创建二叉生成森林
PreOrder(T);//先根遍历二叉生成森林
return(0);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: