图的一般表示有:邻接链表和邻接矩阵,都可表示有向图和无向图。
邻接链表适用于稀疏图,能快速判断两点之间是否相邻;
邻接矩阵适用于较稠密的图。
广度搜索伪代码:
起始顶点元素入队,标记已访问;
while(对不为空) {
对头元素出队,输出;
将此元素的所有为访问的邻接元素(不输出)标记为已访问,并入队。
}
深度搜索伪代码:
起始顶点元素压栈,标记已访问;
while(栈不为空) {
取栈顶元素(不出栈);
if(存在未被访问的邻接元素a) {
输出a,标记为已访问;
将 a 压栈;
}
else // 当前元素的邻接元素都已被访问了
栈顶元素出栈
}
以下是实现代码:
/*
* 图的广度搜索 与 深度搜索
*/
#include<iostream>
#include<list>
#include<stack>
using namespace std;
typedef list<int> ListInt;
typedef stack<int> StackInt;
typedef list<int>::iterator Listptr;
class Graph {
int num; //点的个数
ListInt *head; //指向当前图邻接链表首地址的指针
public:
Graph(int n) {
num = n;
head = new ListInt[10]; // 建 n 个list 容器数组,用head指向其首地址
}
void AddEage(int a, int b) {
head[a].push_back(b);
head[b].push_back(a);
}
void BFT(int v) { // 从v开始执行广度搜索
bool Visited[10] = {0};
ListInt queue;
queue.push_back(v);
Visited[v] = 1;
while(!queue.empty()) {
v = queue.front(); // 出队,访问 已经标记
queue.pop_front();
cout << v << " ";
for(Listptr ptr=head[v].begin(); ptr!=head[v].end(); ptr++) {
if(!Visited[*ptr]) {
Visited[*ptr] = 1;
queue.push_back(*ptr); //
}
}
}
}
void DFT(int v) { // 从v开始执行深度搜索
bool Visited[10] = {0};
StackInt stk;
stk.push(v);
cout << v << " ";
Visited[v] = 1;
while(!stk.empty()) {
v = stk.top();
Listptr ptr;
for(ptr = head[v].begin(); ptr!=head[v].end(); ptr++) {
if(!Visited[*ptr]) {
cout << *ptr << " ";
Visited[*ptr] = 1;
stk.push(*ptr);
break;
}
}
if(ptr == head[v].end())
stk.pop();
}
}
};
int main()
{
Graph g(9);
g.AddEage(0, 1);
g.AddEage(0, 2);
g.AddEage(0, 3);
g.AddEage(0, 4);
g.AddEage(5, 1);
g.AddEage(5, 6);
g.AddEage(3, 7);
g.AddEage(7, 8);
g.DFT(0);
cout << endl;
g.BFT(0);
getchar();
return 0;
}