有向图的邻接表存储,递归和非递归的深度、广度遍历(codeblocks+gcc)

程序功能:

1. 图的邻接表存储

2. 递归深度遍历

3. 非递归深度遍历(借助stack)

4. 递归广度遍历

5. 非递归广度遍历(借助queue)

 

程序中通过条件编译实现,递归与非递归的选择

//#define _RECURSION_TRAVERSE //递归遍历(将下一行注释,此行不注释) #define _NON_RECURSION_TRAVERSE //非递归遍历(节点本身有isVisited域)(将上一行注释,此行不注释)

注释第一行,保留第二行:实现非递归遍历

注释第二行,保留第一行:实现递归遍历

两行都注释或都不注释:出错(无此函数/函数重名)

 

程序所用图的结构

《有向图的邻接表存储,递归和非递归的深度、广度遍历(codeblocks+gcc)》

程序源代码

/***************************************************************** *功 能:利用邻接表存储图,实现其递归与非递归的深度遍历和广度遍历 *作 者: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)》

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/JarvisChu/article/details/6376499
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞