Depth-first search and breadth-first search algorithm, minimum spanning tree two algorithms--c++ implementation of graphs

Source: Internet
Author: User

One: Common graph structure
#ifndef _graph_h#define _graph_h#include <iostream> #include <string.h> #include <assert.h> #include <queue>using namespace::std; #define Max_cost 0x7FFFFFFF//Spend infinitely large set to integer maximum////////////////////////////////////// General graph Structure Template <typename T, typename E>class graph{    Public:bool is_empty () const;bool is_full () const;int get_numvertices () const;       Current vertex number int get_numedges () const;            Current number of sides public:virtual bool Insert_vertex (const t&) = 0;    Insert vertex virtual bool Insert_edge (const t&, const t&, E) = 0;    Insert Edge Virtual int Get_firstneighbor (const t&) const = 0;    Gets the first adjacency vertex of the virtual int get_nextneighbor (const t&, const t&) const = 0;     Next adjacency vertex of an adjacency vertex virtual void print_graph () const = 0;virtual int Get_vertex_index (const t&) const = 0; Get vertex ordinal virtual void Depth_first (const t&) = 0;virtual void Broad_first (const t&) = 0;virtual void Min_spantree_kr Uskal () = 0;virtual void miN_spantree_prim (const t&) = 0;protected:static const int vertices_default_size = 10; Default graph vertex number int max_vertices;int num_vertices;int num_edges;}; Template <typename T, typename E>bool graph<t, E>::is_empty () const{return num_edges = = 0;}  Template <typename T, typename E>bool graph<t, E>::is_full () const{return num_vertices >= max_vertices | |    Num_edges >= max_vertices* (max_vertices-1)/2; Full, divided into vertex full and full}template <typename T, TypeName E>int graph<t, E>::get_numvertices () Const{return num_ vertices;} Template <typename T, typename E>int graph<t, E>::get_numedges () Const{return num_edges;} #define Vertices_ Default_size graph<t, E>::vertices_default_size#define num_vertices graph<t, E>::num_vertices #defi    Ne num_edges graph<t, e>::num_edges#define max_vertices graph<t, e>::max_vertices     #endif/*graph.h*/ 
Two: adjacency matrix diagram structure
#pragma once#include "graph.h"//graph of adjacency matrix notation template <typename T, typename E>class graph_mtx:public graph<t, E&gt ;                   {public:graph_mtx (int);                             ~GRAPH_MTX ();  Public:bool Insert_vertex (const t&); bool Insert_edge (const t&, const t&; E); int Get_firstneighbor (const t&) const;int Get_nextneighbor (const t&, const t&) const;int Get_vertex_index ( const t&) const; t& get_vertex_symbol (const int) const;void print_graph () const;void depth_first (const t&); void Broad_first ( Const t&), void Min_spantree_kruskal (), void Min_spantree_prim (const t&);p rotected:void depth_first (const T                        &amp, BOOL *);p rivate:t* vertices_list;                              Vertex linear table E **edge; Internal Matrix};template <typename T, TypeName e>graph_mtx<t, e>::graph_mtx (int sz = vertices_default_size) {Max_ vertices = SZ > vertices_default_size? Sz:vertices_default_size;vertices_list = new T[max_vertices];edge = newInt*[max_vertices]; Dynamically apply a two-dimensional array for (int i=0; i<max_vertices; ++i) {Edge[i] = new int[max_vertices];}  for (int i=0, i<max_vertices; ++i) for (int j=0; j<max_vertices; ++j) {if (i! = j) Edge[i][j] = max_cost;elseedge[i][j] = 0;} num_vertices = 0;num_edges = 0;} Template <typename T, TypeName E>graph_mtx<t, E>::~graph_mtx () {for (int i=0; i<max_vertices; ++i) Delete [                     ]edge[i]; Separate destruction, and then the total destruction of the delete edge;delete []vertices_list;} Template <typename T, typename E>bool graph_mtx<t, E>::insert_vertex (const t& vert) {if (this->is_ Full ())//derived class function call parent class function, with this or add scope return false;vertices_list[num_vertices++] = Vert;return true;} Template <typename T, typename E>bool graph_mtx<t, E>::insert_edge (const t& vert1, const t& VERT2, E C OST = Max_cost)//due to the existence of the default value of the value, Get_neighbor operation to determine whether equal to max_cost, otherwise it will not get the adjacency vertex {if (This->is_full ())//Full RE  Turn False;int INDEX_V1 = Get_vertex_index (VERT1); Get the vertex ordinal int index_v2 = Get_vertex_index (VERT2); if (index_v1 = =-1 | | index_v2 =-1) return FALSE;EDGE[INDEX_V1][INDEX_V2]    = Edge[index_v2][index_v1] = Cost; Graph ++num_edges;return true;} Template <typename T, typename E>int graph_mtx<t, E>::get_firstneighbor (const t& vert) Const{int index = g Et_vertex_index (vert); if (Index! =-1) {for (int i=0; i<num_vertices; ++i) {if (edge[index][i]! = 0 && Edge[index ][i] = max_cost)//plus Judge Max_costreturn I;}} return-1;} Template <typename T, typename E>int graph_mtx<t, E>::get_nextneighbor (const t& vert1, const t& VERT2 ) Const{int INDEX_V1 = Get_vertex_index (vert1); int index_v2 = Get_vertex_index (VERT2); if (index_v1! =-1 && index_ V2! =-1) {for (int i=index_v2+1; i<num_vertices; ++i) {if (edge[index_v1][i]! = 0 && edge[index_v1][i]! = Max_cos T) return i;}} return-1;} Template <typename T, typename E>int graph_mtx<t, E>::get_vertex_index (const t& vert) const{for (int i=0; I<num_vertices; ++i) {if (vertices_list[i] = = vert) return i;} return-1;} Template <typename T, typename e>t& graph_mtx<t, e>::get_vertex_symbol (const int index) Const{assert ( Index >= 0 && Index < this->get_numvertices ())//assert (index >= 0 && Index < num_vertices) ; Error, because num_vertices itself is we replace the parent class with a macro that element, where use will appear double macro return Vertices_list[index];} Template <typename T, typename e>void graph_mtx<t, E>::p rint_graph () const{if (This->is_empty ()) {cout                      << "Nil graph" << Endl; Null output Nilreturn;} for (int i=0; i<num_vertices; ++i) {cout << vertices_list[i] << "";} cout << endl;for (int i=0; i<num_vertices; ++i) {for (int j=0; j<num_vertices; ++j) {if (edge[i][j]! = max_cost)        cout << Edge[i][j] << ""; elsecout << ' @ ' << ' "; If the weights are infinitely large, replace}cout << vertices_list[i] << Endl;}} Template <typename T, typename e>void graph_mtx<t, E>::d Epth_first (consT t& Vert)//depth First, look for a way to die, no way to go back {int num = this->get_numvertices (); bool *visited = new Bool[num];memset (visited          , 0, sizeof (BOOL) *num); First of all the assignment is false, after the traversal is true, to prevent the graph dead loop Depth_first (vert, visited); cout << "end."; delete []visited;} Template <typename T, typename e>void graph_mtx<t, E>::d epth_first (const t& vert, bool *visited) {cout &lt ;< Vert << "--"; int index = Get_vertex_index (vert); Visited[index] = True;int Neighbor_index = Get_firstneigh Bor (vert), while (neighbor_index! =-1) {if (!visited[neighbor_index]) Depth_first (Get_vertex_symbol (Neighbor_index),   visited); Recursive neighbor_index = Get_nextneighbor (Vert,get_vertex_symbol (Neighbor_index));}} Template <typename T, typename e>void graph_mtx<t, E>::broad_first (const t& vert) {int num = this->get_ Numvertices (); bool *visited = new Bool[num];int index = Get_vertex_index (vert); assert (Index! =-1); memset (visited, 0, siz                    EOF (BOOL) *num);queue<int> que; Through the queue, the metaQue.push (index), cout << vert << "--"; Visited[index] = True;while (!que.empty ()) {int index_tmp = Que.front (); Que.pop (); int neighbor_index = Get_firstneighbor (Get_vertex_symbol (index_tmp)); while (neighbor_index! = -1) {if (!visited[neighbor_index]) {cout << get_vertex_symbol (neighbor_index) << "-"; visited[                  Neighbor_index] = true; After the traversal is true, prevent the graph from looping Que.push (Neighbor_index);} Neighbor_index = Get_nextneighbor (Get_vertex_symbol (index_tmp), Get_vertex_symbol (Neighbor_index));}} cout << "end."; delete []visited;} Min_spactree_kruskaltemplate <typename T, TypeName e>struct _mst_edge{//minimum spanning tree edge structure, <begin, end> for a set of edges, cost for spending int begin;int end; E cost;}; Template <typename T, typename E>int Compare (const void* VP1, const void* VP2) {return (* (_mst_edge<t, e> *) v p1). Cost – (* (* (_mst_edge<t, e> *) VP2). Cost; BOOL _is_same (int *father, int begin, int end)//determine if in the same sub-graph {while (Father[begin]! = begin) Begin = Father[begin];while (Father[end]! = end) End = Fath        Er[end];                       return begin = = END; Determine if the last element has a parent-child relationship}void mark_same (int *father, int begin, int end) {while (Father[begin]! = begin) begin = Father[begin];                    while (father[end]! = end) End = Father[end];father[end] = begin; Let the last element join together, making them the elements of the same sub-graph}template <typename T, TypeName e>void graph_mtx<t, E>::min_spantree_kruskal () {int num = this->get_numvertices (); _mst_edge<t, e> *mst_edge = new _mst_edge<t, e>[num* (num-1)/2];int k = 0 ; for (int i=0; i<num; ++i) for (int j=i+1; j<num; ++j) {//Create an array of valid edge structures, starting with i+1, direct statistical matrix 1/2-side number, no duplicate if (edge[i][j]! = MA X_cost) {mst_edge[k].begin = I;mst_edge[k].end = J;mst_edge[k].cost = Edge[i][j];++k;}}   Qsort (Mst_edge, K, sizeof (_mst_edge<t, e>), compare<t, e>);          Call the quick sort function int *father = new Int[num]; Initialize causes all elements of the parent to point to themselves for (int i=0; i<num; ++i) father[I] = i;for (int i=0; i<num; ++i) if (!_is_same (father, Mst_edge[i].begin, mst_edge[i].end)) {//Decide whether to cout in the same sub-chart << Get_vertex_symbol (Mst_edge[i].begin) << "-" << Get_vertex_symbol (mst_edge[i].end) << ":" <   < Mst_edge[i].cost << Endl;mark_same (father, Mst_edge[i].begin, mst_edge[i].end); After adding mark}delete []father;delete []mst_edge;} Min_spantree_primtemplate <typename T, TypeName E>void graph_mtx<t, E>::min_spantree_prim (const t& vert) {int num = this->get_numvertices ();   int *lowcost = new Int[num];       Minimum spend array int *mst = new Int[num]; Starting position array <mst[i], i> as a set of edges, starting with mst[i]int index = Get_vertex_index (vert), assert (Index! =-1); for (int i=0; i<num; + +) i) {//Initialize so that the default cost per element is vert as the starting edge, so mst[i] corresponds to subscript vert subscript indexif (edge[index][i]! = 0) {Lowcost[i] = edge[index][i];mst[ I] = index;} Elselowcost[i] = 0;} for (int i=0; i<num-1; ++i) {//Xunhua, num elements total num-1 stripe inT min = max_cost;int min_index = -1;for (int j=0; j<num; ++j) {if (lowcost[j]! = 0 && lowcost[j] < min) {//Find Minimum cost min = Lowcost[j];min_index = j;}} cout << Get_vertex_symbol (Mst[min_index]) << "--" << Get_vertex_symbol (Min_index) << ":" &    lt;< min << Endl;lowcost[min_index] = 0; The cost is 0, equivalent to join the generated tree for (int j=0; j<num; ++j) {//loop, if an element to the new element cost less than the default, then update it, int cost = edge[min_index][j];// The next time you loop to the top to find the minimum cost, it's possible to find the minimum cost of the update, which is equivalent to the IF (Cost < Lowcost[j]) {///other vertices pick out the minimum spent on all vertices of the spanning tree each time a new element is added, and update lowcost[j] = costs ; mst[j] = Min_index;}}} delete []lowcost;delete []mst;}
Three: Test part of the test diagram: Test code:
 #include " Graph.h "#include" graph_mtx.h "#define Vertex_size 4int Main () {Graph_mtx<char, int> gm;gm.insert_vertex (' A '); Gm.insert_vertex (' B '); Gm.insert_vertex (' C '); Gm.insert_vertex (' D '); Gm.insert_vertex (' E '); Gm.insert_vertex (' F '); Gm.insert_edge (' A ', ' B ', 6); Gm.insert_edge (' A ', ' C ', 1); Gm.insert_edge (' A ', ' D ', 5); Gm.insert_edge (' B ', ' C ', 5); Gm.insert_edge (' B ', ' E ', 3); Gm.insert_edge (' C ', ' D ', 5); Gm.insert_edge (' C ', ' F ', 4); Gm.insert_edge (' D ', ' F ', 2); Gm.insert_edge (' E ', ' F ', 6); Gm.insert_edge (' C ', ' E ', 6); Gm.print_graph (); cout << "Depth_first Traverse:" < < Endl;gm.depth_first (' A '); cout << endl;cout << "Broad_first traverse:" << endl;gm.broad_first (' A '); cout << endl;cout << "Min_spantree_kruskal:" << Endl;gm.min_spantree_kruskal (); cout << " Min_spantree_prim: "<< endl;gm.min_spantree_prim (' A '); return 0;} 
Test results:

Depth-first search and breadth-first search algorithm, minimum spanning tree two algorithms--c++ implementation of graphs

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.