summaryrefslogtreecommitdiff
path: root/examples/algorithms
diff options
context:
space:
mode:
Diffstat (limited to 'examples/algorithms')
-rw-r--r--examples/algorithms/dfs.zc136
1 files changed, 136 insertions, 0 deletions
diff --git a/examples/algorithms/dfs.zc b/examples/algorithms/dfs.zc
new file mode 100644
index 0000000..054a9d4
--- /dev/null
+++ b/examples/algorithms/dfs.zc
@@ -0,0 +1,136 @@
+import "std.zc"
+
+struct Graph {
+ num_vertices: int;
+ adj_list: Vec<Vec<int>>;
+}
+
+impl Graph {
+ fn new(vertices: int) -> Graph {
+ var g = Graph {
+ num_vertices: vertices,
+ adj_list: Vec<Vec<int>>::new()
+ };
+
+ for i in 0..vertices {
+ g.adj_list.push(Vec<int>::new());
+ }
+
+ return g;
+ }
+
+ fn add_edge(self, src: int, dest: int) {
+ if src < 0 || dest < 0 || src >= self.num_vertices || dest >= self.num_vertices {
+ return;
+ }
+
+ self.adj_list.data[src].push(dest);
+ self.adj_list.data[dest].push(src);
+ }
+
+ fn _dfs_recursive(self, vertex: int, visited: bool*, order: Vec<int>*) {
+ visited[vertex] = true;
+ order.push(vertex);
+
+ var neighbors = self.adj_list.data[vertex];
+ var neighbor_count = (int)neighbors.len;
+ for i in 0..neighbor_count {
+ var neighbor = neighbors.data[i];
+ if !visited[neighbor] {
+ self._dfs_recursive(neighbor, visited, order);
+ }
+ }
+ }
+
+ fn dfs_recursive(self, start: int) -> Vec<int> {
+ var order = Vec<int>::new();
+ if start < 0 || start >= self.num_vertices {
+ return order;
+ }
+
+ var visited = Vec<bool>::new();
+ defer visited.free();
+ for i in 0..self.num_vertices {
+ visited.push(false);
+ }
+
+ self._dfs_recursive(start, visited.data, &order);
+ return order;
+ }
+
+ fn dfs(self, start: int) -> Vec<int> {
+ var order = Vec<int>::new();
+ if start < 0 || start >= self.num_vertices {
+ return order;
+ }
+
+ var visited = Vec<bool>::new();
+ defer visited.free();
+ for i in 0..self.num_vertices {
+ visited.push(false);
+ }
+
+ var stack = Vec<int>::new();
+ defer stack.free();
+ stack.push(start);
+
+ while !stack.is_empty() {
+ var vertex = stack.pop();
+ if visited.data[vertex] {
+ continue;
+ }
+
+ visited.data[vertex] = true;
+ order.push(vertex);
+
+ var neighbors = self.adj_list.data[vertex];
+ var i = (int)neighbors.len - 1;
+ while i >= 0 {
+ var neighbor = neighbors.data[i];
+ if !visited.data[neighbor] {
+ stack.push(neighbor);
+ }
+ i--;
+ }
+ }
+
+ return order;
+ }
+
+ fn free(self) {
+ for i in 0..self.num_vertices {
+ self.adj_list.data[i].free();
+ }
+ self.adj_list.free();
+ }
+}
+
+fn main() {
+ var g = Graph::new(6);
+ defer g.free();
+
+ g.add_edge(0, 1);
+ g.add_edge(0, 2);
+ g.add_edge(0, 3);
+ g.add_edge(1, 4);
+ g.add_edge(3, 5);
+
+ var order_rec = g.dfs_recursive(0);
+ defer order_rec.free();
+ var order_it = g.dfs(0);
+ defer order_it.free();
+
+ "DFS recursive order: "..;
+ for i in 0..(int)order_rec.len {
+ "{order_rec.data[i]} "..;
+ }
+ "";
+
+ "DFS iterative order: "..;
+ for i in 0..(int)order_it.len {
+ "{order_it.data[i]} "..;
+ }
+ "";
+
+ "Expected: 0 1 4 2 3 5";
+}