1、File: graphtypes.h
1 /*
2 * File: graphtypes.h
3 * -------------------
4 * This file defiens low-level data structures that represent graphs
5 *
6 * 定义三种结构
7 * 1、SimpleGraph
8 * 包含两个集合:图中节点的集合;图中弧的集合。
9 * 并且,由于节点在这个公式化的描述中是有名字的,因此,对SimpleGraph
10 * 这个结构来说,包含一个允许用户将节点的名字和节点相对应起来的图是很有用的
11 * 2、Node
12 * 包含节点的名字以及可以指出图中该节点与其它节点的连接关系的集合
13 * 3、Arc
14 * 可以确定弧的结束点,以及一个表示该弧所需代价的数值
15 */
16
17 #ifndef _graphtypes_h
18 #define _graphtypes_h
19
20 #include <string>
21 #include <map>
22 #include <set>
23
24 // 前向引用:定义之前 声明
25 struct Node; // Forward references to these two types so
26 struct Arc; // that the C++ compiler can recognize them
27
28 /*
29 * Type: simpleGraph
30 * ------------------
31 * This type represent a graph and consists of a set of node, a set of
32 * arcs, and a map that creates an association between names and nodes
33 */
34
35 struct SimpleGraph
36 {
37 std::set<Node *> nodes;
38 std::set<Arc *> arcs;
39 std::map<std::string, Node *> nodeMap;
40 };
41
42 /*
43 * Type: Node
44 * -----------
45 * This type represents an individual node and consists of the
46 * name of the node and the set of arcs from this node
47 */
48
49 struct Node
50 {
51 std::string name;
52 std::set<Arc *> arcs;
53 };
54
55 /*
56 * Type: Arc
57 * ---------
58 * This type represents an individual arc and consists of pointers
59 * to the endpoints, along with the cost of traversing the arc
60 */
61
62 struct Arc
63 {
64 Node *start;
65 Node *finish;
66 double cost;
67 };
68
69 #endif
2、File: AirlineGraph.cpp
1 /*
2 * File: AirlineGraph.cpp
3 * ----------------------
4 * This program initializes the graph for the airline example and then
5 * prints the adjacency lists for each of the cities.
6 */
7
8 #include <iostream>
9 //#include <string>
10 #include <set>
11 #include "graphtypes.h"
12
13 void printAdjacencyLists(SimpleGraph &g);
14 void initAirlineGraph(SimpleGraph &airline);
15 void addFlight(SimpleGraph &airline, std::string c1, std::string c2, int miles);
16 void addNode(SimpleGraph &g, std::string name);
17 void addArc(SimpleGraph &g, Node *n1, Node *n2, double cost);
18 extern void depthFirstSearch(Node *node);
19 extern void breadthFirstSearch(Node *node);
20
21 int main()
22 {
23 SimpleGraph airline;
24 initAirlineGraph(airline);
25 std::cout<< "=========== SimpleGraph =========" <<std::endl;
26 // SimpleGraph
27 printAdjacencyLists(airline);
28 std::cout<< "*********************************" <<std::endl;
29 std::cout<< "=========== DepthFirstSearch ==========" <<std::endl;
30 // DepthFirstSearch
31 depthFirstSearch(airline.nodeMap["San Francisco"]);
32 std::cout<< "*********************************" <<std::endl;
33 std::cout<< "=========== test one node->arcs ==========" <<std::endl;
34 // test
35 Node *node = airline.nodeMap["San Francisco"];
36 for(std::set<Arc *>::iterator arc = node->arcs.begin(); arc != node->arcs.end(); arc++)
37 {
38 std::cout<< (*arc)->start->name << " " << (*arc)->finish->name <<std::endl;
39 }
40 std::cout<< "*********************************" <<std::endl;
41 std::cout<< "=========== BreadthFirstSearch ==========" <<std::endl;
42 // BreadthFirstSearch
43 breadthFirstSearch(airline.nodeMap["San Francisco"]);
44 std::cout<< "*********************************" <<std::endl;
45
46 return 0;
47 }
48
49 /*
50 * Function: printAdjacencyLists
51 * Usage: printAdjacencyLists(g)
52 * -----------------------------
53 * pints the adjacency list for each city in the graph
54 */
55
56 void printAdjacencyLists(SimpleGraph &g)
57 {
58 for(std::set<Node *>::iterator node = g.nodes.begin(); node != g.nodes.end(); node++)
59 {
60 std::cout<< (*node)->name << " -> ";
61 bool first = true;
62 for(std::set<Arc *>::iterator arc = (*node)->arcs.begin(); arc != (*node)->arcs.end(); arc++)
63 {
64 if(!first)
65 std::cout<< ", ";
66 std::cout<< (*arc)->finish->name;
67 first = false;
68 }
69 std::cout<< std::endl;
70 }
71 }
72
73 /*
74 * Function: initAirlineGraph
75 * Usage: initAirlineGraph(airline)
76 * --------------------------------
77 * Initializes the airline graph to hold the flight data.
78 * In a real application, the program would almost certainly read this
79 * information from a data file
80 */
81
82 void initAirlineGraph(SimpleGraph &airline)
83 {
84 addNode(airline, "Atlanta");
85 addNode(airline, "Boston");
86 addNode(airline, "Chicago");
87 addNode(airline, "Dallas");
88 addNode(airline, "Denver");
89 addNode(airline, "Los Angeles");
90 addNode(airline, "New York");
91 addNode(airline, "Portland");
92 addNode(airline, "San Francisco");
93 addNode(airline, "Seattle");
94 addFlight(airline, "Atlanta", "Chicago", 599);
95 addFlight(airline, "Atlanta", "Dallas", 725);
96 addFlight(airline, "Atlanta", "New York", 756);
97 addFlight(airline, "Boston", "New York", 191);
98 addFlight(airline, "Boston", "Seattle", 2489);
99 addFlight(airline, "Chicago", "Denver", 907);
100 addFlight(airline, "Dallas", "Denver", 650);
101 addFlight(airline, "Dallas", "Los Angeles", 1240);
102 addFlight(airline, "Dallas", "San Francisco", 1468);
103 addFlight(airline, "Denver", "San Francisco", 954);
104 addFlight(airline, "Portland", "San Francisco", 550);
105 addFlight(airline, "Portland", "Seattle", 130);
106 }
107
108 /*
109 * Function: addFlight
110 * Usage: addFlight(airline, c1, c2, miles)
111 * ----------------------------------------
112 * Adds an arc in each direction between the cities c1 and c2
113 */
114
115 void addFlight(SimpleGraph &airline, std::string c1, std::string c2, int miles)
116 {
117 Node *n1 = airline.nodeMap[c1];
118 Node *n2 = airline.nodeMap[c2];
119 addArc(airline, n1, n2, miles);
120 addArc(airline, n2, n1, miles);
121 }
122
123 /*
124 * Function: addNode
125 * Usage: addNode(g, name)
126 * -----------------------
127 * Adds a new node with the specified name to the graph
128 */
129
130 void addNode(SimpleGraph &g, std::string name)
131 {
132 Node *node = new Node;
133 node->name = name;
134 g.nodes.insert(node);
135 g.nodeMap[name] = node;
136 }
137
138 /*
139 * Function: addArc
140 * Usage: addArc(g, n1, n2, cost)
141 * ------------------------------
142 * Adds a directed arc to the graph connecting n1 to n2
143 */
144
145 void addArc(SimpleGraph &g, Node *n1, Node *n2, double cost)
146 {
147 Arc *arc = new Arc;
148 arc->start = n1;
149 arc->finish = n2;
150 arc->cost = cost;
151 g.arcs.insert(arc);
152 n1->arcs.insert(arc);
153 }
3、File: DepthFirstSearch.cpp
1 /*
2 * File: DepthFirstSearch.cpp
3 * --------------------------
4 */
5
6 #include <iostream>
7 #include "graphtypes.h"
8
9 void visit(Node *node)
10 {
11 std::cout<< node->name <<std::endl;
12 }
13
14 /*
15 * Function: visitUsingDFS
16 * Usage: visitUsingDFS(node, visited);
17 * ------------------------------------
18 * Executes a depth-first search begining at the specified node that
19 * avoids revisiting any nodes in the visited set
20 */
21 void visitUsingDFS(Node *node, std::set<Node *> &visited)
22 {
23 if(visited.count(node))
24 return;
25 visit(node);
26 visited.insert(node);
27 for(std::set<Arc *>::iterator arc = node->arcs.begin(); arc != node->arcs.end(); arc++)
28 {
29 visitUsingDFS((*arc)->finish, visited);
30 }
31 }
32
33 /*
34 * Function: depthFirstSearch
35 * Usage: depthFirstSearch(node);
36 * ------------------------------
37 * Initiates a depth-first search begining at the specified node
38 */
39 void depthFirstSearch(Node *node)
40 {
41 std::set<Node *> visited;
42 visitUsingDFS(node, visited);
43 }
4、File: BreadthFirstSearch.cpp
1 /*
2 * File: BreadthFirsrSearch.cpp
3 * ----------------------------
4 * 实现广度优先算法最简单的方法是使用未处理节点的队列,
5 * 程序的每一步将与当前节点相邻的节点入队。
6 * 因为队列是按顺序处理的,所有从开始节点只有一个跳跃的
7 * 节点将比具有两个跳跃的节点较早的出现在队列中,如此等等。
8 */
9
10 //#include <iostream>
11 #include <queue>
12 #include "graphtypes.h"
13
14 extern void visit(Node *node);
15 /*
16 void visit(Node *node)
17 {
18 std::cout<< node->name <<std::endl;
19 }
20 */
21
22 void breadthFirstSearch(Node *node)
23 {
24 std::set<Node *> visited;
25 std::queue<Node *> unvisit;
26 unvisit.push(node);
27 while(!unvisit.empty())
28 {
29 node = unvisit.front();
30 unvisit.pop();
31 if(!visited.count(node))
32 {
33 visit(node);
34 visited.insert(node);
35 for(std::set<Arc *>::iterator arc = node->arcs.begin(); arc != node->arcs.end(); arc++)
36 unvisit.push((*arc)->finish);
37 }
38 }
39 }
执行: