From 0597917039b18efce155c41c84170a5c5b1598f0 Mon Sep 17 00:00:00 2001 From: Luna Date: Thu, 7 Oct 2021 23:36:26 +0100 Subject: [PATCH 1/3] Added depthFirstSearch.kt --- .../DepthFirstSearch/depthFirstSearch.kt | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 searchingAlgo/DepthFirstSearch/depthFirstSearch.kt diff --git a/searchingAlgo/DepthFirstSearch/depthFirstSearch.kt b/searchingAlgo/DepthFirstSearch/depthFirstSearch.kt new file mode 100644 index 0000000..c15e336 --- /dev/null +++ b/searchingAlgo/DepthFirstSearch/depthFirstSearch.kt @@ -0,0 +1,77 @@ +import java.util.* +import kotlin.collections.HashSet + +class NodeNotFoundException : Throwable("Node was not found") + +class Graph(var value: V, var nodes: MutableSet> = HashSet(), init: Graph.() -> Unit = {}) { + + init { init() } + + fun add(value: V, nodes: MutableSet> = HashSet(), init: Graph.() -> Unit = {}) { + this.nodes.add(Graph(value, nodes, init)) + } + + override fun toString() = value.toString() +} + +fun depthFirstSearch(root: Graph, searchValue: V): Result>> { + + val map = HashMap, Graph>() + val toSearch = Stack>().apply { push(root) } + + while (toSearch.isNotEmpty()) { + + val currentNode = toSearch.pop() + + if (currentNode.value == searchValue) + return Result.success(mapToRoute(root, currentNode, map)) + + currentNode.nodes.forEach { + if (!map.containsKey(it)) { + map[it] = currentNode + toSearch.push(it) + } + } + } + return Result.failure(NodeNotFoundException()) +} + +fun mapToRoute(root: Graph, to: Graph, path: Map, Graph>): List> { + + var position: Graph = to + val result: MutableList> = ArrayList() + + while (position != root) { + result.add(position) + position = path[position]!! + } + + result.add(root) + return result.reversed() +} + +fun main() { + + val graph = Graph(1) { + add(10) { + add(2) { + add(4) + } + add(4) + } + add(2) { + add(7) + } + } + + val result = depthFirstSearch(graph, 4) + + result.fold( + onSuccess = { + println(it.joinToString(separator = " -> ")) + }, + onFailure = { + println("No node with this value was found") + } + ) +} \ No newline at end of file From 2b795d5b6af6e189e89a6af8569c1fbc964282dc Mon Sep 17 00:00:00 2001 From: Luna Date: Fri, 8 Oct 2021 00:24:53 +0100 Subject: [PATCH 2/3] Added depth first search in kotlin --- .../DepthFirstSearch/depthFirstSearch.kt | 83 ++++--------------- 1 file changed, 18 insertions(+), 65 deletions(-) diff --git a/searchingAlgo/DepthFirstSearch/depthFirstSearch.kt b/searchingAlgo/DepthFirstSearch/depthFirstSearch.kt index c15e336..22171ac 100644 --- a/searchingAlgo/DepthFirstSearch/depthFirstSearch.kt +++ b/searchingAlgo/DepthFirstSearch/depthFirstSearch.kt @@ -1,77 +1,30 @@ -import java.util.* -import kotlin.collections.HashSet - -class NodeNotFoundException : Throwable("Node was not found") - -class Graph(var value: V, var nodes: MutableSet> = HashSet(), init: Graph.() -> Unit = {}) { +class Graph(size: Int, init: Graph.() -> Unit) { + val adjacency: Array> = Array(size) { ArrayList() } init { init() } - fun add(value: V, nodes: MutableSet> = HashSet(), init: Graph.() -> Unit = {}) { - this.nodes.add(Graph(value, nodes, init)) - } - - override fun toString() = value.toString() + fun addEdge(node: Int, to: Int) = adjacency[node].add(to) } -fun depthFirstSearch(root: Graph, searchValue: V): Result>> { - - val map = HashMap, Graph>() - val toSearch = Stack>().apply { push(root) } - - while (toSearch.isNotEmpty()) { - - val currentNode = toSearch.pop() - - if (currentNode.value == searchValue) - return Result.success(mapToRoute(root, currentNode, map)) - - currentNode.nodes.forEach { - if (!map.containsKey(it)) { - map[it] = currentNode - toSearch.push(it) - } +fun depthFirstSearch(graph: Graph, current: Int, searched: Array = Array(graph.adjacency.size) { false }) { + if(!searched[current]) { + searched[current] = true + print("$current ") + for (next in graph.adjacency[current]) { + depthFirstSearch(graph, next, searched) } } - return Result.failure(NodeNotFoundException()) -} - -fun mapToRoute(root: Graph, to: Graph, path: Map, Graph>): List> { - - var position: Graph = to - val result: MutableList> = ArrayList() - - while (position != root) { - result.add(position) - position = path[position]!! - } - - result.add(root) - return result.reversed() } fun main() { - - val graph = Graph(1) { - add(10) { - add(2) { - add(4) - } - add(4) - } - add(2) { - add(7) - } + val graph = Graph(4) { + addEdge(0, 1) + addEdge(0, 2) + addEdge(1, 2) + addEdge(2, 0) + addEdge(2, 3) + addEdge(3, 3) } - - val result = depthFirstSearch(graph, 4) - - result.fold( - onSuccess = { - println(it.joinToString(separator = " -> ")) - }, - onFailure = { - println("No node with this value was found") - } - ) + println("Following is Depth First Traversal " + "(Starting from vertex 2)") + depthFirstSearch(graph, 2) } \ No newline at end of file From 7f288a21806c190a8eae8af01528acb5bf6cf702 Mon Sep 17 00:00:00 2001 From: Luna Date: Fri, 8 Oct 2021 00:42:12 +0100 Subject: [PATCH 3/3] Added depth first search in kotlin --- searchingAlgo/DepthFirstSearch/depthFirstSearch.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/searchingAlgo/DepthFirstSearch/depthFirstSearch.kt b/searchingAlgo/DepthFirstSearch/depthFirstSearch.kt index 22171ac..60d9f47 100644 --- a/searchingAlgo/DepthFirstSearch/depthFirstSearch.kt +++ b/searchingAlgo/DepthFirstSearch/depthFirstSearch.kt @@ -1,3 +1,7 @@ +/** + * Creates a Graph with [size] nodes + * @param init constructor for adding the edges of the nodes delegated to the instances + */ class Graph(size: Int, init: Graph.() -> Unit) { val adjacency: Array> = Array(size) { ArrayList() } @@ -6,6 +10,10 @@ class Graph(size: Int, init: Graph.() -> Unit) { fun addEdge(node: Int, to: Int) = adjacency[node].add(to) } +/** + * Prints the route taken when exploring the [graph] starting from [current] + * @param searched an array of booleans relating to whether the relating nodes have been searched + */ fun depthFirstSearch(graph: Graph, current: Int, searched: Array = Array(graph.adjacency.size) { false }) { if(!searched[current]) { searched[current] = true