数据结构——图的邻接矩阵实现
深度优先遍历
**第一步:**构造一个访问数组,大小和顶点数目一样多 初始化都记为0 意为没有访问过
第二步从第一个顶点或者最后一个顶点为起点 判断该顶点有没有走过 再进行DFS函数 最后依次走后面每个顶点(用访问数组判断是否走过)
第三步构造 DFS函数 :
DFS函数 就是从某一顶点开始 根据边是否存在为判断 走次边 然后将其边的另一顶点记为1(走过)
前期准备
typedef int Boolean;//深度遍历的数组为布尔类型 用来标记
Boolean visited[MAXVER];//深度遍历的访问数组
执行部分
/*邻接矩阵的深度遍历算法 访问数组初始化,对每个顶点都可以走一遍 前提是没有走过的*/
Status DFS(MGhaph &G, int i)
{
int j;
visited[i] = true;
cout << "此时访问的顶点为: "<< endl;
cout << G.vexs[i]<< endl;
for (j = 0; j < G.numver; j++)
{
if (G.arc[j][i] != INF && !visited[j])//递归之处 从i为开始 又转到从j的0到顶点数都寻找一遍
DFS(G,j);
}
return 0;
}
Status DFSTraverse(MGhaph &G)
{
int i;
for (i = 0; i < G.numver; i++)//访问数组都记为0 意为 顶点没有被访问过
{
visited[i] = false;
}
for (i = 0; i < G.numver; i++)
{
if (!visited[i])//所有顶点都可以访问(前提是:之前没有被访问过) 且从该顶点开始循环
{
cout << "从" << i << "开始访问" << endl;
DFS(G, i);
}
}
return 0;
}
/*————————深度优先遍历————————*/
思考:深度优先遍历 能够走每一个顶点 且不重复,可以对顶点做一些操作(当然也可以重复 但是复杂度就高了) 属于搜索类的算法吧
广度优先遍历涉及到一个队列
先定义一个队列queue.h
#include<iostream>
//#include <iomanip>
using namespace std;
typedef char elementtype;
typedef int Status;
typedef struct QNode
{
char data;
struct QNode *next;
}QNode, *Queueptr;
typedef struct Queue
{
QNode *head;
QNode *tail;
}Queue;
//初始化队列
Status InitQueue(Queue &Q)
{
Q.head = Q.tail = (Queueptr)malloc(sizeof(QNode));
Q.head->next = NULL;
Q.tail->next = NULL;
return 0;
}
//头指针和尾指针只有一个
//插入元素
Status Enqueue(Queue &Q, elementtype x)
{
Queueptr p = (Queueptr)malloc(sizeof(QNode));//创建一个结点
p->data = x;
p->next = NULL;
Q.tail->next = p;
Q.tail = p;
return 0;
}
Status Dequeue(Queue &Q, elementtype &y)
{
if (Q.head == Q.tail)
{
return NULL;
}
Queueptr q;
q = Q.head->next;
y = q->data;
Q.head->next = q->next;
if (Q.tail == q)
{
Q.tail = Q.head;
}
free(q);
return 0;
}
Status QueueEmpty(Queue &Q)
{
if (Q.head != NULL || Q.tail != NULL)
{
return 1;
}
else
return 0;
}
再在数据结构——图的邻接矩阵实现加上这个
同时#include"queue.h"即可
/*————————实现广度优先遍历————————*/
void BFS(MGhaph &G)
{
char x;
int i, j;
Queue Q;
for (i = 0; i < G.numver; i++)
{
visited[i] = false;//标记
}
InitQueue(Q);//初始化队列
for (i = 0; i < G.numver; i++)
{
if (!visited[i])//如果从未访问过
{
visited[i] = true;//标记 走过的顶点 并输出,并将此顶点存入队列
cout << "此时访问的顶点为: " << endl;
cout << G.vexs[i] << endl;
Enqueue(Q, G.vexs[i]);//将此顶点进入队列
while (!QueueEmpty(Q))//若此时队列不为空时 进入 空时弹出
{
Dequeue(Q,x);//把队列里的一个元素弹出
for (j = 0; j < G.numver; j++)
{
if (G.arc[j][i] != INF && !visited[j])//寻找和i所在的元素有弧的元素
{
visited[j] = true;//标记走过
cout << "从" << j << "开始访问" << endl;
cout <<G.vexs[j] << endl;
Enqueue(Q, G.vexs[j]);//将有联系的顶点元素入队列
}
}
}
}
}
}
广义优先遍历:
1.构造一个队列来存储顶点元素 作为一个中间过程
2.构造一个访问数组 来标记被访问过的顶点
3.设置一个for循环 每次访问的顶点将其存入队列中
再进入while循环(判断队列是否为空 )不为空时进入循环体
弹出队里一个元素
进入for循环 寻找 和该顶点相关的边的顶点
找到相关边顶点之后 存入队列,标记访问过
for循环结束后 还是在while循环里 此时,将队列清空才能跳出
意在大循环里 的队列回到初始化