数据结构 《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条边和 ...
随机推荐
- ccs6.0使用问题记录
ccs6.0使用问题记录 彭会锋 1 编译过程中提示warning " Description Resource Path Location Type #9-D nested commen ...
- VI编辑器学习笔记
VIM的使用 VI是Linux系统中的一种编辑器,它的使用方法和界面与Unix平台十分相似,掌握了VIM的特殊,你可以感觉到它强大的功能与高效.Vim 相对来说较小,无论你使用任何Linux系统,你总 ...
- 3.7 嵌入式SQL
可以放入所有高级语言中去,如C 因为,SQL是过程性语句,需要高级语言的非过程性处理集合的分类处理 一.一般形式 所有的SQL语句都必须加前缀EXEC SQL SQL语句完成结束标志(:或END EX ...
- 聚类算法:ISODATA算法
1. 与K-均值算法的比较 –K-均值算法通常适合于分类数目已知的聚类,而ISODATA算法则更加灵活: –从算法角度看, ISODATA算法与K-均值算法相似,聚类中心都是通过样本均值的迭代运算来决 ...
- firefox hack
@-moz-document url-prefix(){ css选择器 { css样式设置 } }
- 10+优秀“分步引导”jQuery插件(转)
很 多时候一个网站或者一个Web应用出品,为了让你的用户知道你的站点(或应用)有些什么?如何操作?为了让你的用户有更好的体验.往往这个时候都会给你的 站点(应用)添加一个分步指引的效果.然而这样的效果 ...
- splunk 索引过程
术语: Event :Events are records of activity in log files, stored in Splunk indexes. 简单说,处理的日志或话单中中一行记录 ...
- c++ boost 汉字和模式串混用的例子
*=============================================================== * Copyright (C) All rights reserved ...
- 修改weblogic PermGen
vim /weblogic/Oracle/Middleware/wlserver_10.3/common/bin/commEnv.sh 在第144行,增加环境变量:JAVA_VENDOR=Sun #根 ...
- Tomcat性能调优-让小猫飞奔[转]
http://blog.csdn.net/lifetragedy/article/details/7708724 http://blog.csdn.net/lifetragedy/articl ...