[置顶] 有向图的邻接表存储,递归和非递归的深度、广度遍历(codeblocks+gcc)
2011-04-30 16:05
579 查看
程序功能:
1. 图的邻接表存储2. 递归深度遍历
3. 非递归深度遍历(借助stack)
4. 递归广度遍历
5. 非递归广度遍历(借助queue)
程序中通过条件编译实现,递归与非递归的选择
//#define _RECURSION_TRAVERSE //递归遍历(将下一行注释,此行不注释) #define _NON_RECURSION_TRAVERSE //非递归遍历(节点本身有isVisited域)(将上一行注释,此行不注释)
注释第一行,保留第二行:实现非递归遍历
注释第二行,保留第一行:实现递归遍历
两行都注释或都不注释:出错(无此函数/函数重名)
程序所用图的结构
程序源代码
/*****************************************************************
*功 能:利用邻接表存储图,实现其递归与非递归的深度遍历和广度遍历
*作 者:JarvisChu
*时 间:2011-04-30
*****************************************************************/
#include <iostream>
#include <string>
#include <stack>
#include <queue>
using namespace std;
//#define _RECURSION_TRAVERSE //递归遍历(将下一行注释,此行不注释) #define _NON_RECURSION_TRAVERSE //非递归遍历(节点本身有isVisited域)(将上一行注释,此行不注释)
#define MAX_VERTEX_NUM 20 //最大顶点数
/*弧节点的结构,即每个顶点后面的单链表中的节点结构*/
typedef struct ArcNode{
int adjvex; //该弧所指向的顶点的位置
struct ArcNode* nextArc; //下一条弧
string info; //该弧所携带的信息
}ArcNode;
#ifdef _NON_RECURSION_TRAVERSE
/*每个顶点的节点结构,非递归时使用*/
typedef struct VNode{
bool isVisited;
string data; //顶点的数据
ArcNode* fristArc; //指向该顶点所接的单链表的第一个弧节点
}VNode,AdjList[MAX_VERTEX_NUM];
#endif
#ifdef _RECURSION_TRAVERSE
/*每个顶点的节点结构,递归时使用*/
typedef struct VNode{
string data; //顶点的数据
ArcNode* fristArc; //指向该顶点所接的单链表的第一个弧节点
}VNode,AdjList[MAX_VERTEX_NUM];
#endif
/*图的结构*/
typedef struct{
AdjList vertices; //顶点数组
int vexNum; //顶点数
int arcNum; //弧数
int kind; //种类
}Graph;
/*初始化有向图*/
bool InitDiGraph(Graph* pGraph){
pGraph->kind = 0; //有向图
pGraph->vexNum = 5;
pGraph->arcNum = 5;
pGraph->vertices[0].data = "V0"; //顶点V0的邻接表
#ifdef _NON_RECURSION_TRAVERSE
pGraph->vertices[0].isVisited = false;
#endif
ArcNode* node = new ArcNode();
node->adjvex = 1;
node->info = "V0-->V1";
node->nextArc = NULL;
ArcNode* node1 = new ArcNode();
node1->adjvex = 2;
node1->info = "V0-->V2";
node1->nextArc = NULL;
node->nextArc = node1;
pGraph->vertices[0].fristArc = node;
pGraph->vertices[1].data = "V1"; //顶点V1的邻接表
#ifdef _NON_RECURSION_TRAVERSE
pGraph->vertices[1].isVisited = false;
#endif
pGraph->vertices[1].fristArc = NULL;
pGraph->vertices[2].data = "V2"; //顶点V2的邻接表
#ifdef _NON_RECURSION_TRAVERSE
pGraph->vertices[2].isVisited = false;
#endif
node = new ArcNode();
node->adjvex = 3;
node->info = "V2-->V3";
node->nextArc = NULL;
pGraph->vertices[2].fristArc = node;
pGraph->vertices[3].data = "V3"; //顶点V3的邻接表
#ifdef _NON_RECURSION_TRAVERSE
pGraph->vertices[3].isVisited = false;
#endif
node = new ArcNode();
node->adjvex = 0;
node->info = "V3-->V0";
node->nextArc = NULL;
node1 = new ArcNode();
node1->adjvex = 4;
node1->info = "V3-->V4";
node1->nextArc = NULL;
node->nextArc = node1;
pGraph->vertices[3].fristArc = node;
pGraph->vertices[4].data = "V4"; //顶点V4的邻接表
#ifdef _NON_RECURSION_TRAVERSE
pGraph->vertices[4].isVisited = false;
#endif
pGraph->vertices[4].fristArc = NULL;
return true;
}
/*显示有向图*/
bool DisplayDiGraph(Graph diGraph){
cout<<"*******************图信息********************"<<endl;
cout<<"图种类为:"<<diGraph.kind<<endl;
cout<<"顶点数为:"<<diGraph.vexNum<<endl;
cout<<"弧数为:"<<diGraph.arcNum<<endl<<endl;
cout<<"邻接表结构如下"<<endl;
ArcNode* node = NULL;
for(int i=0;i<diGraph.vexNum;i++){
cout<<diGraph.vertices[i].data<<":";
node = diGraph.vertices[i].fristArc;
while(node != NULL){
cout<<"("<<node->adjvex<<","<<node->info<<") ; ";
node = node->nextArc;
}
cout<<endl;
}
return true;
}
#ifdef _NON_RECURSION_TRAVERSE
/*深度优先非递归遍历有向图,利用栈*/
bool Depth_First_Traverse(Graph* pDiGraph){
for(int i=0;i<pDiGraph->vexNum;i++){ //初始化,全为false
pDiGraph->vertices[i].isVisited = false;
}
VNode* vnode;
stack<VNode*> TraverseStack; //用stack实现非递归遍历算法
TraverseStack.push(&(pDiGraph->vertices[0])); //第一个节点入栈
while(!TraverseStack.empty()){
vnode = (VNode*)TraverseStack.top(); //获得栈顶节点
vnode->isVisited = true;
cout<<"遍历:"<<vnode->data<<endl;
TraverseStack.pop();
ArcNode* node = vnode->fristArc;
while(node != NULL){
if(!(pDiGraph->vertices[node->adjvex]).isVisited){
TraverseStack.push(&(pDiGraph->vertices[node->adjvex])); //入栈
}
node = node->nextArc;
}
}
return true;
}
#endif
#ifdef _RECURSION_TRAVERSE
/*深度优先递归遍历时,用来遍历每一个顶点*/
bool DFT(Graph* pDiGraph,bool* visited,int i){
if(!visited[i]){
visited[i] = true; //标志该顶点已被访问了
cout<<"遍历:"<<pDiGraph->vertices[i].data<<endl;
ArcNode* node = pDiGraph->vertices[i].fristArc;//遍历其临街单链表
while(node != NULL){
DFT(pDiGraph,visited,node->adjvex);
node = node->nextArc;
}
}
return true;
}
/*深度优先递归遍历有向图*/
bool Depth_First_Traverse(Graph* pDiGraph){
int size = pDiGraph->vexNum; //顶点数目
bool* visited = new bool[size]; //访问标志数组
for(int i = 0;i < size;i++){ //初始化,全为false
visited[i] = false;
}
for(int i = 0;i<size;i++){ //
DFT(pDiGraph,visited,i);
}
delete[] visited;
return true;
}
#endif
#ifdef _NON_RECURSION_TRAVERSE
/*广度优先非递归遍历有向图,利用队列*/
bool Breadth_First_Traverse(Graph* pDiGraph){
for(int i=0;i<pDiGraph->vexNum;i++){ //初始化,全为false
pDiGraph->vertices[i].isVisited = false;
}
VNode* vnode;
queue<VNode*> TraverseQueue; //用queue实现非递归遍历算法
TraverseQueue.push(&(pDiGraph->vertices[0])); //第一个节点入队
while(!TraverseQueue.empty()){
vnode = (VNode*)TraverseQueue.front(); //获得队首节点
vnode->isVisited = true;
cout<<"遍历:"<<vnode->data<<endl;
TraverseQueue.pop();
ArcNode* node = vnode->fristArc;
while(node != NULL){
if(!(pDiGraph->vertices[node->adjvex]).isVisited){
TraverseQueue.push(&(pDiGraph->vertices[node->adjvex])); //入队
}
node = node->nextArc;
}
}
return true;
}
#endif
#ifdef _RECURSION_TRAVERSE
/*广度优先递归遍历时,用来遍历每一个顶点*/
bool BFT(Graph* pDiGraph,bool* visited,int i){
if(!visited[i]){
visited[i] = true; //标志该顶点已被访问了
cout<<"遍历:"<<pDiGraph->vertices[i].data<<endl;
ArcNode* node = pDiGraph->vertices[i].fristArc;//遍历其临街单链表
while(node != NULL){
if(!pDiGraph->vertices[node->adjvex].isVisited){
pDiGraph->vertices[node->adjvex].isVisited = true;
cout<<"遍历:"<<pDiGraph->vertices[node->adjvex].data<<endl;
}
node = node->nextArc;
// BFT(pDiGraph,visited,node->adjvex);
}
BFT(pDiGraph,visited,node->adjvex);
}
return true;
}
/*广度优先递归遍历有向图*/
bool Breadth_First_Traverse(Graph* pDiGraph){
int size = pDiGraph->vexNum; //顶点数目
bool* visited = new bool[size]; //访问标志数组
for(int i = 0;i < size;i++){ //初始化,全为false
visited[i] = false;
}
for(int i = 0;i<size;i++){ //
BFT(pDiGraph,visited,i);
}
delete[] visited;
}
#endif
int main()
{
Graph diGraph; //有向图
Graph udiGraph; //无向图
InitDiGraph(&diGraph); //初始化有向图,构建
DisplayDiGraph(diGraph); //显示该有向图
cout<<endl<<"***************深度优先遍历结果***********"<<endl;
Depth_First_Traverse(&diGraph); //深度优先遍历
cout<<endl<<"***************广度优先遍历结果***********"<<endl;
Breadth_First_Traverse(&diGraph); //广度优先遍历
return 0;
}
程序运行结果
0 表示有向图相关文章推荐
- 有向图的邻接表存储,递归和非递归的深度、广度遍历(codeblocks+gcc)
- 利用邻接表存储图,实现其递归与非递归的深度遍历和广度遍历
- 【数据结构】邻接表表示法的图的深度广度优先遍历递归和非递归遍历
- 图邻接表存储 深度优先和广度优先遍历
- 图的邻接表存储 深度优先遍历 广度优先遍历 C语言实现
- 图的邻接表存储,以及广度深度遍历
- 图的邻接表存储、创建、深度优先遍历、广度优先遍历
- 大话数据结构 code 第七章 04邻接表深度和广度遍历DFS_BFS
- 【数据结构】邻接矩阵表示法的图的深度广度优先遍历递归和非递归遍历
- 图的邻接表存储 深度优先遍历 广度优先遍历 C语言实现
- 邻接表存储图,深度和广度优先遍历
- 邻接表存储图的深度优先、广度优先遍历非递归算法
- [置顶] 图:图的邻接表创建、深度优先遍历和广度优先遍历代码实现
- 一个连通图,采用邻接表作为存储结构,设计一个算法从顶点v出发的深度优化遍历的非递归过程
- 一个连通图,采用邻接表作为存储结构,设计一个算法从顶点v出发的深度优化遍历的非递归过程
- C语言以邻接表为存储结构的图的构造以及广度优先,深度优先遍历
- 二叉树的深度与广度遍历及前序遍历递归非递归实现
- 有向图遍历,十字链表存储,深度遍历,广度遍历。
- 638. Shopping Offers 深度优先遍历、递归、存储技术(基于递归的动态规划)
- 二叉树的广度优先遍历、深度优先遍历的递归和非递归实现方式 二叉树的遍历方式: 1、深度优先:递归,非递归实现方式 1)先序遍历:先访问根节点,再依次访问左子树和右子树 2)中序遍