图的深度优先搜索 递归和非递归实现 c++版本

本文参考了李春葆版本的数据结构上机指导,但是原版是c代码,

本文用了c++实现,并且修复了深度优先搜索非递归的一个bug。

graph.cpp文件:

#include "graph.h"

#include <queue>

#include <stack>

int visited[MAXV ];

MGraph ::MGraph(int A[100][10], int nn , int ee)

{

e= ee ;

n= nn ;

for (int i=0;i<n;i++)

{

for (int j=0;j<n;j++)

edges[i][j]= A [i][j];

}

}

void MGraph ::DispMat( MGraph g )

{

int i,j;

for (i=0;i<g .n;i++)

{

for (j=0;j<g .n;j++)

cout<< g .edges[i][j]<<"       " ;

cout<<endl;

}

}

ALGragh ::ALGragh(int a[ MAXV][10], int n , int e)

{

ALGragh ::n=n ;

ALGragh ::e=e ;

for (int i=0;i< n;i++)

{

adjlist[i].firstarc= NULL ;

}

for (int i=0;i< n;i++)

for (int j= n-1;j>=0;j--)

{

if (a [i][j]!=0)

{     //作用域里面,必须动态分配。直接写ArcNode p(adjlist[i].firstarc,j,a[i][j])会被析构

ArcNode *p=new ArcNode (adjlist[i].firstarc,j, a [i][j]);

adjlist[i].firstarc=p;

}

}

}

void ALGragh ::DispAdj( ALGragh * G )

{

ArcNode *p;

for (int i=0;i< G->n;i++)

{

p= G ->adjlist[i].firstarc; //p指向第一条边

if (p!=NULL )

cout <<i<<":  " ;

while (p!=NULL )

{

cout<<(p->adjvex)<< "  " ;//输出终点

p=p->nextarc;     //指向下一条边

}

cout<<endl;

}

}

void ALGragh ::DFS( int v, int flag) //深度优先搜索
递归

{

if (flag )

{

memset(visited,0, sizeof (visited));

flag =0;

}

if (v >=n
|| v<0)

{

cout<< "error point!" ;

return ;

}

visited[ v ]=1;

cout<< v <<" 
" ;

ArcNode *p=adjlist[v ].firstarc;

while (p!=NULL )

{

if (!visited[p->adjvex])

DFS(p->adjvex, flag );

p=p->nextarc;

}

}

void ALGragh ::DFS1( int v) //深度优先搜索
非递归

{

memset(visited,0, sizeof (visited));

if (v >=n
|| v<0)

{

cout<< "error point!" ;

return ;

}

stack <ArcNode *>
s;

visited[ v ]=1;

cout<< v <<" 
" ;

ArcNode *q;

s.push(adjlist[ v ].firstarc);

while (!s.empty())

{

q=s.top(); //s.pop();

while (q!=NULL )

{

if (!visited[q->adjvex])

{

visited[q->adjvex]=1;

cout<<q->adjvex<< "  " ;

s.push(adjlist[q->adjvex].firstarc); //定点进栈

break ;

}

else

{

q=q->nextarc;        //与当前结点相连的边都访问了(即往该结点走不下去了)     该节点出栈

if (q==NULL )

s.pop();

}

}

}

}

void ALGragh ::BFS( int v) //广度优先搜索

{

memset(visited,0, sizeof (visited));

if (v >=n
|| v<0)

{

cout<< "error point!" ;

return ;

}

queue <int >
q;

ArcNode *p;

q.push( v );

visited[ v ]=1;

cout<< v <<" 
" ;

while (!q.empty())

{

v =q.front(); q.pop();

p=adjlist[ v ].firstarc;

while (p!=NULL )

{

if (!visited[p->adjvex])

{

visited[p->adjvex]=1;

cout<<p->adjvex<< "  " ;

q.push(p->adjvex);

}

p=p->nextarc;

}

}

}

main.cpp文件:

#include "graph.h"

int main()

{

////////-------图的遍历算法----//////////

/*int A[100][6]={

{0,5,0,7,0,0},

{0,0,4,0,0,0},

{8,0,0,0,0,9},

{0,0,5,0,0,6},

{0,0,0,5,0,0},

{3,0,0,0,1,0}

};*/

int A[100][10]={

0,1,1,1,0,0,0,0,0,0,

1,0,0,1,0,1,1,1,1,0,

0,1,0,1,1,1,0,0,0,0,

0,0,0,0,0,1,0,0,0,0,

0,1,1,1,0,1,0,0,0,0,

0,1,0,0,0,0,0,0,0,0,

0,1,1,1,0,0,0,1,1,0,

0,0,1,1,1,1,1,0,1,0,

0,0,1,1,0,0,0,0,0,0,

0,0,1,0,0,0,0,0,1,0

};

MGraph g(A,10,10);                                                              //图的邻接矩阵类型

ALGragh G(A,10,10);                                                            //图的临界表类型

g.DispMat(g);

G.DispAdj(&G);

G.DFS(0,1); cout<<endl;

G.DFS1(0); cout<<endl;

graph.h文件:

#include "C++global.h"//图的数据结构

typedef int InfoType;

#define MAXV 100   //最大顶点个数

//------------------------------------//

//-----------用邻接矩阵存储-------------//

class VertexType     //顶点类型

{

private :

int no;      //顶点编号

InfoType info; //顶点的其他信息;

};

class MGraph     //图的定义

{

public :

void DispMat(MGraph g);

MGraph(){n=0;e=0;memset(edges,0, sizeof (edges));}

MGraph( int A[100][10],int n, int e);

private :

int edges[MAXV ][ MAXV]; //邻接矩阵

int n,e;               //顶点数,弧数

VertexType vexs[MAXV ]; //图的邻接矩阵类型。

};

//------------------------------------//

//------------------------------------//

//------------用临界表存储-------------//

class VNode ;

class ArcNode             //弧结点结构类

{

friend class   ALGragh;

//friend class VNode;

public :

ArcNode(){}

ArcNode( ArcNode *next , int adj, int i)

{              adjvex= adj ;            nextarc= next;        info= i ;    }

private :

int adjvex;

ArcNode *nextarc;    //指向下一条弧的指针

InfoType info;       //弧先关信息,这里存放权值

};

class VNode {               //头结点类

//friend class ArcNode;

friend class   ALGragh;

private :

int data;              //顶点信息

ArcNode *firstarc;     //指向第一条弧

};

typedef VNode AdjList[ MAXV ]; //AdjList是临界表类型

class   ALGragh {     //图的临界表类型

public :

ALGragh();

ALGragh( int a[MAXV ][10], int n, int e
);

void DispAdj(ALGragh *G);

void DFS(int v, int flag);

void DFS1(int v); //深度优先
非递归

void BFS(int v);

private :

AdjList adjlist;     //邻接表

int n,e;

};

输出:

图的深度优先搜索 递归和非递归实现 c++版本

时间: 2025-01-14 04:57:35

图的深度优先搜索 递归和非递归实现 c++版本的相关文章

图的深度优先遍历(DFS) c++ 非递归实现

深搜算法对于程序员来讲是必会的基础,不仅要会,更要熟练.ACM竞赛中,深搜也牢牢占据着很重要的一部分.本文用显式栈(非递归)实现了图的深度优先遍历,希望大家可以相互学习. 栈实现的基本思路是将一个节点所有未被访问的“邻居”(即“一层邻居节点”)踹入栈中“待用”,然后围绕顶部节点猛攻,每个节点被访问后被踹出.读者可以自己画图分析一下,难度并不大. 代码写的比较随意,仅供参考.~ #include <iostream> #include <stack> using namespace

图的深度优先搜索(DFS)简介与实现(递归与非递归方法)

上一篇刚刚学习了C++图的实现,今天对深度优先搜索(DFS)进行了一定学习,并作出一定实现.在本文中图的实现,以及相应的函数调用(如获得第一个邻接顶点.获得下一个邻接顶点等)均是基于上文中的实现,故如果想参考测试代码,还需导入上文中相应的类定义.关于C++图的实现可参考此处,这里实现了对图的邻接表以及邻接矩阵两种实现,而本文的深度优先搜索对于上面两种实现均是可行的. 当然,对于图的深度优先搜索的相关定义,本文也不再过多赘述,维基的解释应该就足够,下面将探讨其实现. 1.深度优先搜索的非递归实现:

二叉树的广度优先遍历、深度优先遍历的递归和非递归实现方式

二叉树的遍历方式: 1.深度优先:递归,非递归实现方式 1)先序遍历:先访问根节点,再依次访问左子树和右子树 2)中序遍历:先访问左子树,再访问根节点吗,最后访问右子树 3)后序遍历:先访问左子树,再访问右子树,最后访问根节点 2.广度优先     按照树的深度,一层一层的访问树的节点 1 package Solution; 2 3 import java.util.LinkedList; 4 import java.util.Queue; 5 import java.util.Stack; 6

图的深度优先搜索及拓扑排序

本文将介绍图的深度优先搜索,并实现基于深度优先搜索的拓扑排序(拓扑排序适用于有向无环图,下面详细介绍). 1. 图的深度优先遍历要解决的问题 图的深度优先搜索与树的深度优先搜索类似,但是对图进行深度优先搜索要解决一个问题,那就是顶点的重复访问,假设图中存在一个环路A-B-C-A,那么对顶点A进行展开后得到B,对B进行展开后得到C,然后对C进行展开后得到A,然后A就被重复访问了... 这显然是不对的!我们需要用一个状态变量来记录一个顶点被访问和被展开的状态.在<算法导论>中,作者使用3种颜色来对

二叉树递归与非递归遍历,最近公共父节点算法

#include <iostream> #include <stack> using namespace std; #define MAX 100 //字符串最大长度 typedef struct Node //二叉树结点 { char data; Node *lchild,*rchild; } *Btree; void createBT(Btree &t); //先序构造二叉树 void preorder(Btree &t); //二叉树递归先序遍历 void i

二叉树之AVL树的平衡实现(递归与非递归)

这篇文章用来复习AVL的平衡操作,分别会介绍其旋转操作的递归与非递归实现,但是最终带有插入示例的版本会以递归呈现. 下面这张图绘制了需要旋转操作的8种情况.(我要给做这张图的兄弟一个赞)后面会给出这八种情况对应平衡实现. [1] 情况1-2: 这种需要旋转的结构一般称之为LL型,需要右旋 (顺时针旋转). 我用一个图来抽象一下这两个情况,画的不好,我尽量表达吧. 此时需要对A进行平衡操作,方法为: 将A的左子树换为B的右子树. B的右子树换为A. 非递归实现的代码为: 1 void rotate

数据结构二叉树的递归与非递归遍历之 实现可编译(1)java

前一段时间,学习数据结构的各种算法,概念不难理解,只是被C++的指针给弄的犯糊涂,于是用java,web,javascript,分别去实现数据结构的各种算法. 二叉树的遍历,本分享只是以二叉树中的先序遍历为例进行说明,中序遍历和后序遍历,以此类推! 二叉树递归与非递归遍历的区别,虽然递归遍历,跟容易读懂,代码量少,运算快,但是却容易出现溢出的问题,所以所以非递归遍历,在处理千万级的运算量时会先的很有用处. 二叉树的先序遍历:先访问根节点,再访问先后访问左右节点.如图: 二叉树的递归遍历之java

二叉树三种遍历递归及非递归实现(Java)

import java.util.Stack; //二叉树三种遍历递归及非递归实现(Java) public class Traverse { /******************定义二叉树**************************/ private final int MAX_SIZE = 10; //链式存储 public static class BinaryTreeNode { int mValue; BinaryTreeNode mLeft; BinaryTreeNode

数据结构——二叉树遍历之“递归与非递归遍历”

简述 二叉树的遍历分为先序遍历.中序遍历和后序遍历.如下图所示: 递归遍历 private void bianli1(List<Integer> list, TreeNode root) { // 先序遍历 if (root == null) { return; } list.add(root.val); bianli1(list, root.left); bianli1(list, root.right); } private void bianli2(List<Integer>