图的广度与深度搜索(邻接链表)

来源:互联网 发布:2016美国经济非农数据 编辑:程序博客网 时间:2024/05/18 03:24

图的一般表示有:邻接链表和邻接矩阵,都可表示有向图和无向图。

邻接链表适用于稀疏图,能快速判断两点之间是否相邻;

邻接矩阵适用于较稠密的图。


广度搜索伪代码: 

起始顶点元素入队,标记已访问;

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;}


1 0
原创粉丝点击