这里放一下关于图的遍历
废话少说直接上~~
首先是图的结构类型:
typedef struct ANode{
int adjvex; //编号
struct ANode *nextarc; //链接指针
Elemtype weight; //权值
}ArcNode;
typedef struct VNode{
Elemtype data; //头结点数据
ArcNode *firstarc; //指向第一个边结点
};
typedef struct{
VNode adjlist[MAX];
int n;int e;
}ArcGraph;
图的创建(邻接链表):
void CreateAdj(ArcGraph *&G,int A[MAXV][MAXV],int n,int e){
ArcNode *p;
G=new ArcGraph;//为G申请储存空间
for(int i=0;i<n;i++)//置空
G->adjlist[i].firstarc=NULL;
for(int i=0;i<n;i++)
for(int j=n-1;j>=0;j--)
if(A[i][j]!=0&&A[i][j]!=MAX)//如果邻接矩阵存在边
{
p = new ArcNode;//创建结点
p->adjvex = j;//编号输入
p->weight = A[i][j];//权值输入
p->nextarc = G->adjlist[i].firstarc;//头插法插入
G->adjlist[i].firstarc = p;
}
G->n=n;G->e=e;
}
po出两种算法
- 深度遍历算法(递归)
递归深度遍历分这么几步
首先初始化访问数组=0
然后先将访问数组的访问顶点=1
接着该顶点的邻接点w
最后就开始循环递归的
while(w存在)
{
if(w未被访问)
递归
w转到下一个邻接点
}
int visitedDPS[MAX]={0};//全局标记数组
void DFS(ArcGraph *G,int v){
ArcNode *p;
visitedDPS[v]=1;//访问标记
cout<<v<<" ";//输出访问编号
p=G->adjlist[v].firstarc;//指向第一个顶点
while (p!=NULL)
{
if(visitedDPS[p->adjvex]==0)//如果访问标记为0
DFS(G,p->adjvex);//递归调用
p=p->nextarc;//指向下一个结点
}
}
- 广度优先遍历
首先还是初始化访问数组=0
然后访问顶点=1
将访问顶点的序号v加入队列queue
最后还是循环
while(queue为非空)
{
v=队列的头元素
w=v的第一个邻接点
while(w非空)
if(w的访问数组标记=0)
访问数组=1
w加入队列queue
w=顶点v的下一个邻接点
int visitedBFS[MAX]={0};//全局标记数组
void BFS(ArcGraph *G,int v){
ArcNode *p;
queue<int>que;//初始化队列
//int visited[MAX];
for(int i=0;i<G->n;i++)visitedBFS[i]=0;//初始化标记数组
cout<<v<<" ";//编号
visitedBFS[v]=1;//访问标记
que.push(v);//进队操作
while (!que.empty())
{
/*
在标记顶点序号的时候本以为p->adjvex就可以了 但是debug出现了segfault(原因尚未知)
但是考虑到出顶点的时候利用队列的front函数得到那个序号就可以了!!
*/
int w=que.front();//这里真的是踩了一个大坑了!!!!
que.pop();//顶点w点出队
p = G->adjlist[w].firstarc;//指向w的第一个邻接点
while (p != NULL) {
if (visitedBFS[p->adjvex] == 0)//如果邻接点未被访问,访问该节点
{
cout << p->adjvex<< " " ;
visitedBFS[p->adjvex] = 1;
que.push(p->adjvex);//顶点进队
}
p = p->nextarc;//寻找下一个邻接点
}
}
}
这里主函数的调用
int main(){
int A[5][5]={{ 0 , 8 ,MAX, 5 ,MAX},
{MAX, 0 , 3 ,MAX,MAX},
{MAX,MAX, 0 ,MAX, 6 },
{MAX,MAX, 9 , 0 ,MAX},
{MAX,MAX,MAX,MAX, 0 }};
ArcGraph *G;
int n=5,e=5;
CreateAdj(G,A,n,e);
cout<<"This is adjacency list which your created."<<endl;
DispAdj(G);
cout<<endl<<"This is Depth First Search."<<endl;
DFS(G,0);
cout<<endl<<"This is Breadth First Search."<<endl;
BFS(G,0);
return 0;
}
在深度优先遍历中使用了递归的方法,该算法的时间复杂度为O(n²),广度优先遍历中使用了标记数组的方法,该算法的时间复杂度为O(n+e),其中e为图中边的个数.对于空间复杂度来说,两者的储存类型都是一样的,所以空间复杂度是相同的.综合对比两个遍历算法,各有优点,而且遍历所得的结果不同,在实际使用的时候要考虑问题的实现方法来综合考量两种算法.