本文参考了李春葆版本的数据结构上机指导,但是原版是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;
};