第7章 图
2016-03-28 22:32
330 查看
leetcode刷了一大半,数组,链表,树,队列和栈的题目已经做了好多,感觉比较扎实了。突然发现后面好多关于图算法的问题,没办法,又继续开始学习“图”这种数据结构。折腾了一天,把图的创建,深度优先级遍历(DFS)和广度优先级遍历(BFS)都用c++写出来了,算法参照了《算法导论》和《数据结构和算法》。
遍历是各种图操作的基本思路,所以一定要熟练掌握。
注:
1. 图的表示采用了邻接链表,因为这种结构在存储方面比较节约空间,在遍历时的时间复杂度也比用邻接矩阵时更好,两种遍历都为O(V+E)
2.下面以有向图来展示遍历的过程,无向图类似,只是在添加边调用
遍历是各种图操作的基本思路,所以一定要熟练掌握。
注:
1. 图的表示采用了邻接链表,因为这种结构在存储方面比较节约空间,在遍历时的时间复杂度也比用邻接矩阵时更好,两种遍历都为O(V+E)
2.下面以有向图来展示遍历的过程,无向图类似,只是在添加边调用
addEdge()函数时再加一条相反的边即可。
/* A C++ Program to demonstrate adjacency list representation of graphs Create a adjacency list representation of graphs BFS based on adjacency list representation of graphs BFS based on adjacency list representation of graphs */ #include <iostream> #include <queue> #include <vector> using namespace std; // A structure to represent an adjacency list node struct AdjListNode { int dest; AdjListNode* next; AdjListNode(int d): dest(d), next(NULL) {} }; // A structure to represent an adjacency list struct AdjList { AdjListNode *head; // pointer to head node of list AdjList(): head(NULL) {} }; // A structure to represent a graph. A graph is an array of adjacency lists. // Size of array will be V (number of vertices in graph) struct Graph { int V; AdjList* array; Graph(int vertex): V(vertex) { array = new AdjList[V]; for(int i = 0; i < vertex; i++) array[i].head = new AdjListNode(i); } ~Graph() { AdjListNode* it; AdjListNode* prev; for(int i = 0; i < V; i++) { it = array[i].head; while(it) { prev = it; it = it->next; delete prev; } } delete[] array; } }; // A utility function to create a new adjacency list node AdjListNode* newAdjListNode(int dest) { AdjListNode* node = new AdjListNode(dest); return node; } // A utility function that creates a graph of V vertices Graph* createGraph(int V) { Graph* graph = new Graph(V); return graph; } // Adds an edge to an directed graph void addEdge(struct Graph* graph, int src, int dest) { //src to dest AdjListNode* node = newAdjListNode(dest); node->next = graph->array[src].head->next; graph->array[src].head->next = node; /* //dest to src (if it's an undirected graph) node = newAdjListNode(src); node->next = graph->array[dest].head; graph->array[dest].head = node; */ } // A utility function to print the adjacenncy list representation of graph void printGraph(struct Graph* graph) { for (int v = 0; v < graph->V; ++v) { AdjListNode* pCrawl = graph->array[v].head; cout << endl << " Adjacency list of vertex " << v << endl << " "; while (pCrawl) { cout << pCrawl->dest << "-> "; pCrawl = pCrawl->next; } cout << "#" << endl; } } void BreadthFirstSearch(Graph* graph) { cout << "BreadthFirstSearch print: " << endl; queue<AdjListNode*> q; vector<bool> visited(graph->V, false); AdjListNode* cur = NULL; for(int i = 0; i < graph->V; i++) { if(!visited[i]) { visited[i] = true; cout << i << " -> "; cur = graph->array[i].head; q.push(cur); while(!q.empty()) { cur = q.front(); if(cur->dest < graph->V) cur = graph->array[cur->dest].head; q.pop(); while(cur) { if(!visited[cur->dest]) { visited[cur->dest] = true; cout << cur->dest << " -> "; q.push(cur); } cur = cur->next; } } } } cout << "#" << endl; } void DFS_helper(Graph* graph, int v, vector<bool>& visited) { cout << v << " -> "; if(v >= graph->V || v < 0) return; visited[v] = true; AdjListNode* cur = graph->array[v].head->next; while(cur) { DFS_helper(graph, cur->dest, visited); cur = cur->next; } } void DepthFirstSearch(Graph* graph) { cout << "DepthFirstSearch print: " << endl; vector<bool> visited(graph->V, false); for(int i = 0; i < graph->V; i++) { if(!visited[i]) DFS_helper(graph, i, visited); } cout << "#" << endl; } // Driver program to test above functions int main() { // create the graph given in above fugure int V = 7; struct Graph* graph = createGraph(V); addEdge(graph, 0, 2); addEdge(graph, 0, 1); addEdge(graph, 1, 4); addEdge(graph, 1, 3); addEdge(graph, 2, 6); addEdge(graph, 2, 5); addEdge(graph, 3, 7); // print the adjacency list representation of the above graph printGraph(graph); //BFS and DFS BreadthFirstSearch(graph); DepthFirstSearch(graph); return 0; }
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- 渗透技术一瞥(图)
- 图片引发的溢出危机(图)
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例