Skip to content

Commit 861a1bf

Browse files
committed
update ch4
1 parent 4542d78 commit 861a1bf

File tree

16 files changed

+718
-7
lines changed

16 files changed

+718
-7
lines changed

README.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,12 @@ Algorithms, 4th edition textbook code (using c++)
6464

6565
## ch4. Graphs
6666

67-
| REF | PROGRAM | DESCRIPTION / JAVADOC | REF | PROGRAM | DESCRIPTION / JAVADOC |
68-
| :---------------------------------------------------------: | :-----------------------------------------------: | :---------------------------: | :---------------------------------------------------------: | :----------------------------------------------------------: | :---------------------------: |
69-
| [-](https://algs4.cs.princeton.edu/41graph/index.php#-) | [Graph.h](ch4/head/Graph.h) | undirected graph | [-](https://algs4.cs.princeton.edu/41graph/index.php#-) | [GraphGenerator.java](https://algs4.cs.princeton.edu/41graph/GraphGenerator.java.html) | generate random graphs |
70-
| [-](https://algs4.cs.princeton.edu/41graph/index.php#-) | [DepthFirstSearch.h](ch4/head/DepthFirstSearch.h) | depth-first search in a graph | [-](https://algs4.cs.princeton.edu/41graph/index.php#-) | [NonrecursiveDFS.h](ch4/head/NonrecursiveDFS.h) | DFS in a graph (nonrecursive) |
71-
| [4.1](https://algs4.cs.princeton.edu/41graph/index.php#4.1) | [DepthFirstPaths.h](ch4/head/DepthFirstPaths.h) | paths in a graph (DFS) | [4.2](https://algs4.cs.princeton.edu/41graph/index.php#4.2) | [BreadthFirstPaths.h](ch4/head/BreadthFirstPaths.h) | paths in a graph (BFS) |
67+
| REF | PROGRAM | DESCRIPTION / JAVADOC | REF | PROGRAM | DESCRIPTION / JAVADOC |
68+
| :---------------------------------------------------------: | :-----------------------------------------------: | :-----------------------------: | :---------------------------------------------------------: | :----------------------------------------------------------: | :---------------------------: |
69+
| [-](https://algs4.cs.princeton.edu/41graph/index.php#-) | [Graph.h](ch4/head/Graph.h) | undirected graph | [-](https://algs4.cs.princeton.edu/41graph/index.php#-) | [GraphGenerator.java](https://algs4.cs.princeton.edu/41graph/GraphGenerator.java.html) | generate random graphs |
70+
| [-](https://algs4.cs.princeton.edu/41graph/index.php#-) | [DepthFirstSearch.h](ch4/head/DepthFirstSearch.h) | depth-first search in a graph | [-](https://algs4.cs.princeton.edu/41graph/index.php#-) | [NonrecursiveDFS.h](ch4/head/NonrecursiveDFS.h) | DFS in a graph (nonrecursive) |
71+
| [4.1](https://algs4.cs.princeton.edu/41graph/index.php#4.1) | [DepthFirstPaths.h](ch4/head/DepthFirstPaths.h) | paths in a graph (DFS) | [4.2](https://algs4.cs.princeton.edu/41graph/index.php#4.2) | [BreadthFirstPaths.h](ch4/head/BreadthFirstPaths.h) | paths in a graph (BFS) |
72+
| [4.3](https://algs4.cs.princeton.edu/41graph/index.php#4.3) | [CC.h](ch4/head/CC.h) | connected components of a graph | [-](https://algs4.cs.princeton.edu/41graph/index.php#-) | [Bipartite.h](ch4/head/Bipartite.h) | bipartite or odd cycle (DFS) |
73+
| [-](https://algs4.cs.princeton.edu/41graph/index.php#-) | [BipartiteX.h](ch4/head/BipartiteX.h) | bipartite or odd cycle (BFS) | [-](https://algs4.cs.princeton.edu/41graph/index.php#-) | [Cycle.h](ch4/head/Cycle.h) | cycle in a graph |
74+
| | | | | | |
7275

ch4/10_Cycle/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
cmake_minimum_required(VERSION 3.8)
2+
project(10_Cycle)
3+
4+
set(CMAKE_CXX_STANDARD 14)
5+
6+
set(SOURCE_FILES main.cpp ../head/Graph.h ../head/GraphGenerator.h ../head/DepthFirstSearch.h ../head/EulerianCycle.h)
7+
add_executable(10_Cycle ${SOURCE_FILES})

ch4/10_Cycle/main.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include <iostream>
2+
#include "../head/Cycle.h"
3+
4+
using namespace std;
5+
6+
/**
7+
* Unit tests the {@code Cycle} data type.
8+
*
9+
* @param args the command-line arguments
10+
*/
11+
int main() {
12+
string filename = "/home/ace/AceDev/C++/algorithm/ch4/data/tinyG.txt";
13+
Graph G(filename);
14+
Cycle finder(G);
15+
if (finder.hasCycle()) {
16+
auto cyc = finder.getcycle();
17+
while (!cyc.empty()) {
18+
cout << cyc.top() << " ";
19+
cyc.pop();
20+
}
21+
cout << endl;
22+
} else
23+
cout << "Graph is acyclic" << endl;
24+
}

ch4/7_CC/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
cmake_minimum_required(VERSION 3.8)
2+
project(7_CC)
3+
4+
set(CMAKE_CXX_STANDARD 14)
5+
6+
set(SOURCE_FILES main.cpp ../head/Graph.h ../head/GraphGenerator.h ../head/DepthFirstSearch.h)
7+
add_executable(7_CC ${SOURCE_FILES})

ch4/7_CC/main.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include <iostream>
2+
#include <queue>
3+
#include "../head/CC.h"
4+
5+
using namespace std;
6+
7+
/**
8+
* Unit tests the {@code BreadthFirstPaths} data type.
9+
*
10+
* @param args the command-line arguments
11+
*/
12+
int main() {
13+
string filename = "/home/ace/AceDev/C++/algorithm/ch4/data/tinyG.txt";
14+
Graph g(filename);
15+
CC cc(g);
16+
int m = cc.getcount();
17+
cout << m << " components" << endl;
18+
vector<queue<int>> components(m);
19+
for (int v = 0; v < g.getV(); ++v) {
20+
components[cc.getid(v)].push(v);
21+
}
22+
// print results
23+
for (int i = 0; i < m; ++i) {
24+
while (!components[i].empty()) {
25+
auto v = components[i].front();
26+
components[i].pop();
27+
cout << v << " ";
28+
}
29+
cout << endl;
30+
}
31+
}

ch4/8_Bipartite/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
cmake_minimum_required(VERSION 3.8)
2+
project(8_Bipartite)
3+
4+
set(CMAKE_CXX_STANDARD 14)
5+
6+
set(SOURCE_FILES main.cpp ../head/Graph.h ../head/GraphGenerator.h ../head/DepthFirstSearch.h)
7+
add_executable(8_Bipartite ${SOURCE_FILES})

ch4/8_Bipartite/main.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include <iostream>
2+
#include <queue>
3+
#include "../head/GraphGenerator.h"
4+
#include "../head/Bipartite.h"
5+
6+
using namespace std;
7+
8+
/**
9+
* Unit tests the {@code Bipartite} data type.
10+
*
11+
* @param args the command-line arguments
12+
*/
13+
int main() {
14+
int V1 = 5;
15+
int V2 = 8;
16+
int E = 4;
17+
int F = 6;
18+
// create random bipartite graph with V1 vertices on left side,
19+
// V2 vertices on right side, and E edges; then add F random edges
20+
Graph G = GraphGenerator::bipartite(V1, V2, E);
21+
uniform_int_distribution<> dis(0, V1 + V2 - 1);
22+
for (int i = 0; i < F; ++i) {
23+
int v = dis(g);
24+
int w = dis(g);
25+
G.addEdge(v, w);
26+
}
27+
28+
cout << G << endl;
29+
Bipartite b(G);
30+
if (b.getisBipartite()) {
31+
cout << "Graph is bipartite" << endl;
32+
for (int v = 0; v < G.getV(); ++v) {
33+
cout << v << " : " << b.getcolor(v) << endl;
34+
}
35+
} else {
36+
cout << "Graph has an odd-length cycle: ";
37+
auto odd = b.oddCycle();
38+
while (!odd.empty()) {
39+
cout << odd.top() << " ";
40+
odd.pop();
41+
}
42+
}
43+
}

ch4/9_BipartiteX/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
cmake_minimum_required(VERSION 3.8)
2+
project(9_BipartiteX)
3+
4+
set(CMAKE_CXX_STANDARD 14)
5+
6+
set(SOURCE_FILES main.cpp ../head/Graph.h ../head/GraphGenerator.h ../head/DepthFirstSearch.h)
7+
add_executable(9_BipartiteX ${SOURCE_FILES})

ch4/9_BipartiteX/main.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include <iostream>
2+
#include <queue>
3+
#include "../head/GraphGenerator.h"
4+
#include "../head/BipartiteX.h"
5+
6+
using namespace std;
7+
8+
/**
9+
* Unit tests the {@code Bipartite} data type.
10+
*
11+
* @param args the command-line arguments
12+
*/
13+
int main() {
14+
int V1 = 5;
15+
int V2 = 8;
16+
int E = 4;
17+
int F = 6;
18+
// create random bipartite graph with V1 vertices on left side,
19+
// V2 vertices on right side, and E edges; then add F random edges
20+
Graph G = GraphGenerator::bipartite(V1, V2, E);
21+
uniform_int_distribution<> dis(0, V1 + V2 - 1);
22+
for (int i = 0; i < F; ++i) {
23+
int v = dis(g);
24+
int w = dis(g);
25+
G.addEdge(v, w);
26+
}
27+
28+
cout << G << endl;
29+
BipartiteX b(G);
30+
if (b.getisBipartite()) {
31+
cout << "Graph is bipartite" << endl;
32+
for (int v = 0; v < G.getV(); ++v) {
33+
cout << v << " : " << b.getcolor(v) << endl;
34+
}
35+
} else {
36+
cout << "Graph has an odd-length cycle: ";
37+
auto odd = b.oddCycle();
38+
while (!odd.empty()) {
39+
cout << odd.front() << " ";
40+
odd.pop();
41+
}
42+
}
43+
}

ch4/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@ project(ch4)
44
set(CMAKE_CXX_STANDARD 14)
55

66
add_subdirectory(1_Graph)
7+
add_subdirectory(2_GraphGenerator)
78
add_subdirectory(3_DepthFirstSearch)
89
add_subdirectory(4_NonrecursiveDFS)
910
add_subdirectory(5_DepthFirstPaths)
1011
add_subdirectory(6_BreadthFirstPaths)
12+
add_subdirectory(7_CC)
13+
add_subdirectory(8_Bipartite)
14+
add_subdirectory(9_BipartiteX)
15+
add_subdirectory(10_Cycle)
1116

1217
add_subdirectory(temp)

ch4/head/Bipartite.h

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
#ifndef CH4_BIPARTITE_H
2+
#define CH4_BIPARTITE_H
3+
4+
#include "../head/Graph.h"
5+
6+
7+
/**
8+
* The {@code Bipartite} class represents a data type for
9+
* determining whether an undirected graph is bipartite or whether
10+
* it has an odd-length cycle.
11+
* The <em>isBipartite</em> operation determines whether the graph is
12+
* bipartite. If so, the <em>color</em> operation determines a
13+
* bipartition; if not, the <em>oddCycle</em> operation determines a
14+
* cycle with an odd number of edges.
15+
* <p>
16+
* This implementation uses depth-first search.
17+
* The constructor takes time proportional to <em>V</em> + <em>E</em>
18+
* (in the worst case),
19+
* where <em>V</em> is the number of vertices and <em>E</em> is the number of edges.
20+
* Afterwards, the <em>isBipartite</em> and <em>color</em> operations
21+
* take constant time; the <em>oddCycle</em> operation takes time proportional
22+
* to the length of the cycle.
23+
* See {@link BipartiteX} for a nonrecursive version that uses breadth-first
24+
* search.
25+
* <p>
26+
* For additional documentation, see <a href="https://algs4.cs.princeton.edu/41graph">Section 4.1</a>
27+
* of <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
28+
*
29+
* @author Robert Sedgewick
30+
* @author Kevin Wayne
31+
*/
32+
class Bipartite {
33+
public:
34+
/**
35+
* Determines whether an undirected graph is bipartite and finds either a
36+
* bipartition or an odd-length cycle.
37+
*
38+
* @param G the graph
39+
*/
40+
Bipartite(Graph &G) : isBipartite(true), color(G.getV()), marked(G.getV()), edgeTo(G.getV()) {
41+
for (int v = 0; v < G.getV(); v++) {
42+
if (!marked[v]) {
43+
dfs(G, v);
44+
}
45+
}
46+
}
47+
48+
/**
49+
* Returns true if the graph is bipartite.
50+
*
51+
* @return {@code true} if the graph is bipartite; {@code false} otherwise
52+
*/
53+
bool getisBipartite() {
54+
return isBipartite;
55+
}
56+
57+
/**
58+
* Returns the side of the bipartite that vertex {@code v} is on.
59+
*
60+
* @param v the vertex
61+
* @return the side of the bipartition that vertex {@code v} is on; two vertices
62+
* are in the same side of the bipartition if and only if they have the
63+
* same color
64+
* @throws IllegalArgumentException unless {@code 0 <= v < V}
65+
* @throws UnsupportedOperationException if this method is called when the graph
66+
* is not bipartite
67+
*/
68+
bool getcolor(int v) {
69+
validateVertex(v);
70+
if (!isBipartite)
71+
throw runtime_error("graph is not bipartite");
72+
return color[v];
73+
}
74+
75+
/**
76+
* Returns an odd-length cycle if the graph is not bipartite, and
77+
* {@code null} otherwise.
78+
*
79+
* @return an odd-length cycle if the graph is not bipartite
80+
* (and hence has an odd-length cycle), and {@code null}
81+
* otherwise
82+
*/
83+
stack<int> oddCycle() {
84+
return cycle;
85+
}
86+
87+
private:
88+
// throw an IllegalArgumentException unless {@code 0 <= v < V}
89+
void validateVertex(int v) {
90+
int V = marked.size();
91+
if (v < 0 || v >= V)
92+
throw runtime_error("vertex " + to_string(v) + " is not between 0 and " + to_string(V - 1));
93+
}
94+
95+
void dfs(Graph G, int v) {
96+
marked[v] = true;
97+
for (int w : G.getadj(v)) {
98+
// short circuit if odd-length cycle found
99+
if (!cycle.empty()) return;
100+
101+
// found uncolored vertex, so recur
102+
if (!marked[w]) {
103+
edgeTo[w] = v;
104+
color[w] = !color[v];
105+
dfs(G, w);
106+
} // if v-w create an odd-length cycle, find it
107+
else if (color[w] == color[v]) {
108+
isBipartite = false;
109+
cycle.push(w); // don't need this unless you want to include start vertex twice
110+
for (int x = v; x != w; x = edgeTo[x]) {
111+
cycle.push(x);
112+
}
113+
cycle.push(w);
114+
}
115+
}
116+
}
117+
118+
119+
private:
120+
bool isBipartite; // is the graph bipartite?
121+
vector<bool> color; // color[v] gives vertices on one side of bipartition
122+
vector<bool> marked; // marked[v] = true iff v has been visited in DFS
123+
vector<int> edgeTo; // edgeTo[v] = last edge on path to v
124+
stack<int> cycle; // odd-length cycle
125+
};
126+
127+
#endif //CH4_BIPARTITE_H

0 commit comments

Comments
 (0)