数据结构 《2》----基于邻接表表示的图的实现 DFS(递归和非递归), BFS
图通常有两种表示方法: 邻接矩阵 和 邻接表
对于稀疏的图,邻接表表示能够极大地节省空间。
以下是图的数据结构的主要部分:
struct Vertex{
ElementType element; //节点的名字
Edge *next; //所包含的边组成的单链表的头指针
};
struct Edge{
int adj; //节点的标号(0-number of nodes)
Edge *next;
};
注意,实际应用中,节点都有名字,而不是数字,所以我们需要提供从名字到标号的映射。
最简单的方法就是 Hash(散列表),或者二叉查找树之类的能够快速提供查询的数据结构。
本文的处理较为简单: 节点的名字是 'a' ---- 'z', 所以映射通过简单的运算即可实现: node id = node name - 'a'.
- // copyright @ L.J.SHOU Jan.13, 2014
- #include "graph.h"
- #include <ctime>
- #include <iostream>
- #include <stack>
- #include <queue>
- using namespace std;
- typedef char ElementType;
- typedef Vertex* Graph;
- enum Color{WHITE, GRAY, BLACK};
- struct Edge
- {
- int vertex;
- int weight;
- Edge *next;
- };
- struct Vertex
- {
- Color color;
- ElementType element;
- int start, finish;
- Edge *next;//head of adjacent list
- };
- Graph Create(Graph graph, int n)
- {
- graph = new Vertex[n];
- for(int i=0; i<n; ++i)
- {
- graph[i].color = WHITE;
- graph[i].element = i + 'a';
- graph[i].start = 0;
- graph[i].finish = 0;
- graph[i].next = NULL;
- }
- return graph;
- }
- // Reset Graph
- void Clear(Graph graph, int n)
- {
- for(int i=0; i<n; ++i)
- {
- graph[i].color = WHITE;
- graph[i].start = 0;
- graph[i].finish = 0;
- }
- }
- Graph DeleteGraph(Graph graph, int n)
- {
- for(int i=0; i<n; ++i)
- {
- Edge* head(graph[i].next), *next(NULL);
- while(head)
- {
- next = head->next;
- delete head;
- head = next;
- }
- }
- delete [] graph;
- return NULL;
- }
- // return the outdegree of vertex i
- int OutDegree(Graph g, int i)
- {
- int num(0);
- Edge* link(g[i].next);
- while(link)
- {
- link = link->next;
- ++ num;
- }
- return num;
- }
- // test whether edge(i, j) exists
- bool Exist(Graph g, int i, int j)
- {
- Edge *link(g[i].next);
- while(link && link->vertex != j)
- link = link->next;
- if(link == NULL)
- return false;
- else
- return true;
- }
- bool InsertEdge(Graph g, int i, int j)
- {
- if(Exist(g, i, j)){
- cout << "edge (" << i << "," << j << ") already existed" << endl;
- return false;
- }
- Edge *edge(NULL);
- edge = new struct Edge;
- edge->vertex = j;
- edge->next = g[i].next;
- g[i].next = edge;
- return true;
- }
- bool DeleteEdge(Graph g, int i, int j)
- {
- if(!Exist(g, i, j)){
- cout << "edge (" << i << "," << j << ") doesn't exist" << endl;
- return false;
- }
- Edge *cur(g[i].next), *pre(cur);
- while(cur && cur->vertex != j)
- {
- pre = cur;
- cur = cur->next;
- }
- if(pre == NULL)
- { // delete head edge
- g[i].next = cur->next;
- delete cur;
- }
- else
- {
- pre->next = cur->next;
- delete cur;
- }
- return true;
- }
- // print adjacent list
- void OutPut(Graph g, int n)
- {
- Edge *edge(NULL);
- for(int i=0; i<n; ++i)
- {
- cout << g[i].element << "->";
- edge = g[i].next;
- while(edge)
- {
- cout << g[edge->vertex].element << "->";
- edge = edge->next;
- }
- cout << "NULL" << endl;
- }
- }
- void DFS(Graph graph, int n)
- {
- cout << "DFS: " << endl;;
- Clear(graph, n);
- for(int i=0; i<n; ++i)
- {
- if(graph[i].color == WHITE)
- DFSVisit(graph, i);
- }
- cout << endl;
- cout << "DFS_stack: " << endl;
- Clear(graph, n);
- for(int i=0; i<n; ++i)
- {
- if(graph[i].color == WHITE)
- DFSVisitStack(graph, i);
- }
- cout << endl;
- }
- // recursive DFS
- void DFSVisit(Graph graph, int i)
- {
- static int time(0);
- Edge *link(graph[i].next);
- cout << graph[i].element << " ";
- graph[i].color = GRAY;
- graph[i].start = ++time;
- while(link)
- {
- if(graph[link->vertex].color == WHITE)
- DFSVisit(graph, link->vertex);
- link = link->next;
- }
- graph[i].finish = ++time;
- graph[i].color = BLACK;
- }
- // non-recursive DFS
- void DFSVisitStack(Graph g, int i)
- {
- static int time(0);
- struct Edge* edge;
- int vertex;
- stack<int> s;
- //visit vertex i
- cout << g[i].element << " ";
- g[i].color = GRAY;
- g[i].start = ++time;
- s.push(i);
- while(!s.empty())
- {
- vertex = s.top();
- edge = g[vertex].next;
- while(edge)
- {
- if(g[edge->vertex].color == WHITE)
- {
- s.push(edge->vertex);
- cout << g[edge->vertex].element << " ";
- g[edge->vertex].start = ++time;
- g[edge->vertex].color = GRAY;
- break;
- }
- edge = edge->next;
- }
- //vertex's neigbours have been visited
- if(edge == NULL){
- s.pop();
- g[vertex].color = BLACK;
- g[vertex].finish = ++time;
- }
- }
- }
- /////////////////////////////////////////////////////////////
- // search all vertices that can be rearched from Source s ///
- // compute the distances from source s /// ///////////////
- /////////////////////////////////////////////////////////////
- void BFS(Graph g, int n, int s)
- {
- queue<int> q;
- Edge *edge(NULL);
- int vertex;
- //visit source vertex
- Clear(g, n);
- cout << "BFS: " << endl;;
- cout << g[s].element << " ";
- g[s].color = GRAY;
- q.push(s);
- while(!q.empty())
- {
- //dequeue
- vertex = q.front();
- q.pop();
- //all the adjacent vertices
- edge = g[vertex].next;
- while(edge)
- {
- if(g[edge->vertex].color == WHITE){
- g[edge->vertex].color = GRAY;
- cout << g[edge->vertex].element << " ";
- //enqueue
- q.push(edge->vertex);
- }
- edge = edge->next;
- }
- g[vertex].color = BLACK;
- }//end of while
- cout << endl;
- }
- int main()
- {
- Graph graph;
- int num_vertices = 8;
- graph = Create(graph, num_vertices);
- InsertEdge(graph,0,1);
- InsertEdge(graph,1,2);
- InsertEdge(graph,2,3);
- InsertEdge(graph,3,2);
- InsertEdge(graph,4,0);
- InsertEdge(graph,1,5);
- InsertEdge(graph,2,6);
- InsertEdge(graph,3,7);
- InsertEdge(graph,1,4);
- InsertEdge(graph,4,5);
- InsertEdge(graph,5,6);
- InsertEdge(graph,6,7);
- InsertEdge(graph,7,7);
- InsertEdge(graph,6,5);
- OutPut(graph, num_vertices);
- DFS(graph, num_vertices);
- BFS(graph, num_vertices, 0);
- graph = DeleteGraph(graph, num_vertices);
- return 0;
- }
数据结构 《2》----基于邻接表表示的图的实现 DFS(递归和非递归), BFS的更多相关文章
- 图的基本操作(基于邻接表):图的构造,深搜(DFS),广搜(BFS)
#include <iostream> #include <string> #include <queue> using namespace std; //表结点 ...
- SDUT 2142 数据结构实验之图论二:基于邻接表的广度优先搜索遍历
数据结构实验之图论二:基于邻接表的广度优先搜索遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Descript ...
- 数据结构C++使用邻接表实现图
定义邻接表存储的图类.[实验要求] (1)创建一个邻接表存储的图:(2)返回图中指定边的权值:(3)插入操作:向图中插入一个顶点,插入一条边:(4)删除操作:从图中删除一个顶点,删除一条边:(5)图的 ...
- 无向图的 DFS 和 BFS实现 (以邻接表存储的图)
#include <iostream> #include <queue> using namespace std; #define MaxVertexNum 10 typede ...
- 数据结构二叉树的递归与非递归遍历之java,javascript,php实现可编译(1)java
前一段时间,学习数据结构的各种算法,概念不难理解,只是被C++的指针给弄的犯糊涂,于是用java,web,javascript,分别去实现数据结构的各种算法. 二叉树的遍历,本分享只是以二叉树中的先序 ...
- 数据结构作业——图的存储及遍历(邻接矩阵、邻接表+DFS递归、非递归+BFS)
邻接矩阵存图 /* * @Author: WZY * @School: HPU * @Date: 2018-11-02 18:35:27 * @Last Modified by: WZY * @Las ...
- SDUT2142数据结构实验之图论二:基于邻接表的广度优先搜索遍历
http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2142&cid=1186 题目描述 给定一个无向连通图,顶点编号从0到n-1,用广度优先搜 ...
- Invitation Cards(邻接表+逆向建图+SPFA)
Time Limit: 8000MS Memory Limit: 262144K Total Submissions: 17538 Accepted: 5721 Description In ...
- 基于邻接表的长度为k的简单路径的求解
描述 一个连通图采用邻接表作为存储结构.设计一个算法,判断无向图中任意给定的两点是否存在一条长度为k的简单路径. 输入 多组数据,每组m+3数据行.第一行有两个数字n,m和k,代表有n个顶点,m条边和 ...
随机推荐
- WAMP 403 Forbidden禁止访问 的解决办法
修改httpd.conf文件 # onlineoffline tag - don't remove Require local To # onlineoffline tag - don't remov ...
- valuestack,stackContext,ActionContext.之间的关系
者之间的关系如下图所示: relation ActionContext 一次Action调用都会创建一个ActionContext 调用:ActionContext context = ActionC ...
- javaWeb学习之运用myeclipse结合tomcat开发一些简单的jsp和service
servlet是什么? servlet是java服务器端编程.不同于我们之前写的一般的java应用程序,Servlet程序是运行在服务器上的,服务器有很多种.....现在只是用过 tomcat ...
- SQL Server数据库(SQL Sever语言 事务)
事务:保障流程的完整执行保证程序某些程序在运行时同时成功同时失败,保证程序的安全性 begin tran --在流程开始的位置加 --此处写SQL语句 if @@error>0 --ERRORS ...
- class、interface、struct的区别
1 struct和class有什么区别 1.1默认的继承访问权限 Struct是public的,class是private的. 你可以写如下的代码: struct A { char a; }; str ...
- css——子代与后代选择器
一直都以为,子代选择器与后代选择器作用是一样的,都是选择一个元素下面的子元素,直到今天才明白: 1.子代选择器(用<连接):ul>li 子选择器仅仅选择ul包围的 子元素 中的 li元素, ...
- 发送广播BroadcastReceiver
import android.os.Bundle;import android.app.Activity;import android.content.Intent;import android.vi ...
- [css]邮件的写法
<style type="text/css"> /* Client-specific Styles */ #outlook a{paddin ...
- ASP.NET MVC学习之路由篇(3)
根据路由输出链接 既然是网站开发自然少不了链接,我们已经学会了强大的路由,但是还缺少一步就是能够将这些路由的路径输出到页面,下面我们就开始学习如何输出路由路径. 首先我们的路由注册部分如下所示: 1 ...
- [转载]查看基于Android 系统单个进程内存、CPU使用情况的几种方法
转载自: http://www.linuxidc.com/Linux/2011-11/47587.htm 一.利用Android API函数查看1.1 ActivityManager查看可用内存. A ...