Repository: gazolla/Kotlin-Algorithm Branch: master Commit: 76aee604a45f Files: 54 Total size: 102.1 KB Directory structure: gitextract_bjd7u91h/ ├── .idea/ │ ├── Kotlin-Algorithm.iml │ ├── compiler.xml │ ├── copyright/ │ │ └── profiles_settings.xml │ ├── inspectionProfiles/ │ │ ├── Project_Default.xml │ │ └── profiles_settings.xml │ ├── kotlinc.xml │ ├── markdown-navigator/ │ │ └── profiles_settings.xml │ ├── markdown-navigator.xml │ ├── misc.xml │ ├── modules.xml │ ├── vcs.xml │ └── workspace.xml ├── BinarySearch/ │ ├── BinarySearch.kt │ └── README.markdown ├── Combinatorics/ │ └── Combinatorics.kt ├── Compression/ │ ├── Compresion.kt │ ├── CompressionTest.kt │ └── README.markdown ├── DepthFirstSearch/ │ ├── AdjacencyList.kt │ ├── DepthFirstSearch.kt │ ├── Edge.kt │ ├── Graphable.kt │ ├── README.markdown │ └── Vertex.kt ├── Deque/ │ ├── Deque.kt │ ├── DequeTest.kt │ └── README.markdown ├── InsertionSort/ │ ├── InsertionSort.kt │ └── README.markdown ├── LinearSearch/ │ ├── LinearSearch.kt │ └── README.markdown ├── LinkedList/ │ ├── LinkedList.kt │ └── README.markdown ├── MergeSort/ │ ├── MergeSort.kt │ └── README.markdown ├── OrderedArray/ │ ├── OrderedArray.kt │ └── README.markdown ├── OrderedSet/ │ ├── OrderedSet.kt │ └── README.markdown ├── Queue/ │ ├── Queue.kt │ └── README.markdown ├── QuickSort/ │ ├── QuickSort.kt │ └── README.markdown ├── README.markdown ├── SelectionSort/ │ ├── README.markdown │ └── SelectionSort.kt ├── ShellSort/ │ ├── README.markdown │ └── ShellSort.kt ├── Shuffle/ │ ├── README.markdown │ └── Shuffle.kt ├── Stack/ │ ├── README.markdown │ └── Stack.kt └── Tree/ ├── README.markdown └── Tree.kt ================================================ FILE CONTENTS ================================================ ================================================ FILE: .idea/Kotlin-Algorithm.iml ================================================ ================================================ FILE: .idea/compiler.xml ================================================ ================================================ FILE: .idea/copyright/profiles_settings.xml ================================================ ================================================ FILE: .idea/inspectionProfiles/Project_Default.xml ================================================ ================================================ FILE: .idea/inspectionProfiles/profiles_settings.xml ================================================ ================================================ FILE: .idea/kotlinc.xml ================================================ ================================================ FILE: .idea/markdown-navigator/profiles_settings.xml ================================================ ================================================ FILE: .idea/markdown-navigator.xml ================================================ ================================================ FILE: .idea/misc.xml ================================================ 1.8 ================================================ FILE: .idea/modules.xml ================================================ ================================================ FILE: .idea/vcs.xml ================================================ ================================================ FILE: .idea/workspace.xml ================================================ 1492877006538 ================================================ FILE: BinarySearch/BinarySearch.kt ================================================ import java.util.* /** * Created by gazollajunior on 03/04/16. */ fun > binarySearch(list: List, key: T): Int? { var rangeStart = 0 var rangeEnd = list.count() while (rangeStart < rangeEnd) { val midIndex = rangeStart + (rangeEnd - rangeStart)/2 if (list[midIndex] == key) { return midIndex } else if (list[midIndex] < key) { rangeStart = midIndex + 1 } else { rangeEnd = midIndex } } return null } fun > binarySearchRec(list: List, key: T): Optional { require(list == list.sorted()) fun helper(start: Int, end: Int): Optional { val mid: Int = start + (end - start) / 2 if (end < start) return Optional.empty() if (key == list[mid]) { return Optional.of(mid) } else if (key < list[mid]) { return helper(start, mid - 1) } else { return helper(mid + 1, end) } } return helper(0, list.count()) } fun main(args: Array) { println("\nOrdered list:") val ordered = listOf("Adam", "Clark", "John", "Tim", "Zack") println(ordered) val name = "John" println("\n$name is in the position ${binarySearch(ordered, name)} in the ordered List.") println("\n$name is in the position ${binarySearchRec(ordered, name)} in the ordered List.") } ================================================ FILE: BinarySearch/README.markdown ================================================ # Binary Search Binary Search is a search algorithm that finds the position of a target value, whether alone or part of a record, within a sorted array. It works by comparing the target value to the middle element of the array; if they are not equal, the lower or upper half of the array is eliminated depending on the result and the search is repeated until the position of the target value is found. source: [Wikipedia page for Binary Search](https://en.wikipedia.org/wiki/Binary_search_algorithm) ## The code Here is an iterative implementation of the binary search algorithm in Kotlin: ```kotlin fun > binarySearch(list: List, key: T): Int? { var rangeStart = 0 var rangeEnd = list.count() while (rangeStart < rangeEnd) { val midIndex = rangeStart + (rangeEnd - rangeStart)/2 if (list[midIndex] == key) { return midIndex } else if (list[midIndex] < key) { rangeStart = midIndex + 1 } else { rangeEnd = midIndex } } return null } ``` ================================================ FILE: Combinatorics/Combinatorics.kt ================================================ /** * Created by gazollajunior on 06/04/16. */ fun factorial(number:Long):Long{ if (number <= 1) return 1 else return factorial(number - 1) * number } fun permutations(n:Long, k:Long):Long{ return factorial(n)/factorial(n-k) } fun combinations(n:Long, k:Long):Long{ return permutations(n,k)/factorial(k) } fun main(args: Array) { println("0 factorial is ${factorial(0)}") println("1 factorial is ${factorial(1)}") println("2 factorial is ${factorial(2)}") println("3 factorial is ${factorial(3)}") println("4 factorial is ${factorial(4)}") println("5 factorial is ${factorial(5)}\n") println("permutations(9,4) ${permutations(9,4)}") println("permutations(10,8) ${permutations(10,8)}") println("permutations(20,6) ${permutations(20,6)}") println("permutations(22,6) ${permutations(22,6)}\n") println("combinations(9,4) ${combinations(9,4)}") println("combinations(10,8) ${combinations(10,8)}") println("combinations(20,6) ${combinations(20,6)}") println("combinations(22,6) ${combinations(22,6)}\n") } ================================================ FILE: Compression/Compresion.kt ================================================ package compression /** * Calculation of Run Length Encoding using Tail Recursion * Created by Andy on 05/05/2016. */ tailrec fun runLengthEncoding(text:String,prev:String=""):String { if (text.length == 0){ return prev } val initialChar = text.get(0) val count = text.takeWhile{ it==initialChar }.count() return runLengthEncoding(text.substring(count),prev + "$count$initialChar" ) } ================================================ FILE: Compression/CompressionTest.kt ================================================ import compression.runLengthEncoding import org.jetbrains.spek.api.Spek import org.junit.Assert.* /** * Spek BDD test for Run Length Encoding */ class RunLengthEncodingTest: Spek({ given("Empty String"){ it("Returns Empty String"){ assertEquals("",runLengthEncoding("")) } } given("Single character"){ it("Returns 1A"){ assertEquals("1B",runLengthEncoding("B")) } } given("All same Character"){ it("It returns 5A"){ assertEquals("5A",runLengthEncoding("AAAAA")) } } given("A mix of characters then "){ it("It returns expected encoding"){ assertEquals("5A3B4C2A",runLengthEncoding("AAAAABBBCCCCAA")) } } given("A longer string then "){ it("It returns expected encoding without overflow"){ assertEquals("5A3B4C7A3B4C7A3B4C7A3B4C7A3B4C7A3B4C7A3B4C7A3B4C7A3B4C2A", runLengthEncoding("AAAAABBBCCCCAAAAAAABBBCCCCAAAAAAABBBCCCCAAAAAAABBBCCCCAAAAAAABBBCCCCAAAAAAABBBCCCCAAAAAAABBBCCCCAAAAAAABBBCCCCAAAAAAABBBCCCCAA")) } } }) ================================================ FILE: Compression/README.markdown ================================================ # Run-length encoding Run-length encoding (RLE) is a very simple form of lossless data compression in which runs of data (that is, sequences in which the same data value occurs in many consecutive data elements) are stored as a single data value and count, rather than as the original run. This is most useful on data that contains many such runs. Consider, for example, simple graphic images such as icons, line drawings, and animations. It is not useful with files that don't have many runs as it could greatly increase the file size. RLE may also be used to refer to an early graphics file format supported by CompuServe for compressing black and white images, but was widely supplanted by their later Graphics Interchange Format. RLE also refers to a little-used image format in Windows 3.x, with the extension rle, which is a Run Length Encoded Bitmap, used to compress the Windows 3.x startup screen. source:Wikipedia ## The code ```kotlin tailrec fun runLengthEncoding(text:String,prev:String=""):String { if (text.length == 0){ return prev } val initialChar = text.get(0) val count = text.takeWhile{ it==initialChar }.count() return runLengthEncoding(text.substring(count),prev + "$count$initialChar" ) } ``` Code by: - [Andy Bowes](https://github.com/AndyBowes) ================================================ FILE: DepthFirstSearch/AdjacencyList.kt ================================================ class AdjacencyList>: Graphable { var adjacencyMap: MutableMap, MutableList>> = mutableMapOf() private fun addDirectedEdge(source: Vertex, destination: Vertex, weight: Double?) { val edge = Edge(source, destination, weight) adjacencyMap[source]?.add(edge) } private fun addUndirectedEdge(vertices: Pair, Vertex>, weight: Double?) { val (source, destination) = vertices addDirectedEdge(source, destination, weight) addDirectedEdge(destination, source, weight) } override fun createVertex(data: T): Vertex { val vertex = Vertex(data) adjacencyMap[vertex] ?: run { adjacencyMap[vertex] = mutableListOf() } return vertex } override fun add(type: EdgeType, source: Vertex, destination: Vertex, weight: Double?) = when(type) { is Directed -> { addDirectedEdge(source, destination, weight) } is Undirected -> { addUndirectedEdge(Pair(source, destination), weight) } } override fun weight(source: Vertex, destination: Vertex): Double? { val edges = adjacencyMap[source] edges?.let { it.forEach { edge -> if (edge.destination == destination) return edge.weight } } return null } override fun edges(source: Vertex): MutableList>? = adjacencyMap[source] override fun toString(): String { var result = "" for ((vertex, edges) in adjacencyMap) { var edgeString = "" for ((index, edge) in edges.withIndex()) { if (index != edges.count() - 1) { edgeString += "${edge.destination}, " } else { edgeString += "${edge.destination}" } } result += "$vertex ---> [ $edgeString ] \n" } return result } } ================================================ FILE: DepthFirstSearch/DepthFirstSearch.kt ================================================ fun main(args: Array) { val adjacencyList = AdjacencyList() val s = adjacencyList.createVertex("S") val a = adjacencyList.createVertex("A") val b = adjacencyList.createVertex("B") val c = adjacencyList.createVertex("C") val d = adjacencyList.createVertex("D") val f = adjacencyList.createVertex("F") val g = adjacencyList.createVertex("G") val e = adjacencyList.createVertex("E") adjacencyList.add(Undirected(), s, a) adjacencyList.add(Undirected(), a, b) adjacencyList.add(Undirected(), a, d) adjacencyList.add(Undirected(), a, c) adjacencyList.add(Undirected(), b, d) adjacencyList.add(Undirected(), d, g) adjacencyList.add(Undirected(), d, f) adjacencyList.add(Undirected(), f, e) print(adjacencyList) print(depthFirstSearch(s, e, adjacencyList)) } fun depthFirstSearch(start: VertexString, end: VertexString, graph: AdjacencyList): Stack { val visited: MutableSet = mutableSetOf() val stack = Stack() stack.push(start) visited.add(start) var vertex = stack.peek() loop@while (vertex != null && vertex != end) { val neighbors = graph.edges(vertex) if (neighbors != null && neighbors.count() > 0) { for (edge in neighbors) { if (!visited.contains(edge.destination)) { visited.add(edge.destination) stack.push(edge.destination) print("$stack") vertex = stack.peek() continue@loop } } } else { print("backtrack from $vertex") stack.pop() vertex = stack.peek() continue } print("backtrack from $vertex") stack.pop() vertex = stack.peek() } return stack } ================================================ FILE: DepthFirstSearch/Edge.kt ================================================ sealed class EdgeType class Directed() : EdgeType() class Undirected(): EdgeType() data class Edge>(var source: Vertex, var destination: Vertex, val weight: Double?) ================================================ FILE: DepthFirstSearch/Graphable.kt ================================================ interface Graphable> { fun createVertex(data: T): Vertex fun add(type: EdgeType, source: Vertex, destination: Vertex, weight: Double? = 0.0) fun weight(source: Vertex, destination: Vertex): Double? fun edges(source: Vertex): MutableList>? } ================================================ FILE: DepthFirstSearch/README.markdown ================================================ # Depth-First Search Depth-first search (DFS) is an algorithm for traversing or searching tree or graph data structures. One starts at the root (selecting some arbitrary node as the root in the case of a graph) and explores as far as possible along each branch before backtracking. A version of depth-first search was investigated in the 19th century by French mathematician Charles Pierre Trémaux as a strategy for solving mazes. Algorithms that use depth-first search as a building block include: * Finding connected components. * Topological sorting. * Finding 2-(edge or vertex)-connected components. * Finding 3-(edge or vertex)-connected components. * Finding the bridges of a graph. * Generating words in order to plot the Limit Set of a Group. * Finding strongly connected components. * Planarity testing[7][8] * Solving puzzles with only one solution, such as mazes. (DFS can be adapted to find all solutions to a maze by only including nodes on the current path in the visited set.) * Maze generation may use a randomized depth-first search. * Finding biconnectivity in graphs. source:Wikipedia ================================================ FILE: DepthFirstSearch/Vertex.kt ================================================ data class Vertex>(val data: T) { override fun toString(): String { return "$data" } } ================================================ FILE: Deque/Deque.kt ================================================ package deque /** * Implementation of the Deque functionality which provides a double ended queue. * * This implementation of Deque is backed by a MutableList * * Created by Andy Bowes on 05/05/2016. */ class Deque(){ var backingList : MutableList = arrayListOf() fun addFirst(element:T){ backingList.add(0,element) } fun getFirst():T?{ if (backingList.isEmpty()){ return null } val value = backingList.first() removeFirst() return value } fun removeFirst(){ if (backingList.isNotEmpty()) backingList.removeAt(0) } fun peekFirst(): T?{ return if (backingList.isNotEmpty()) backingList.first() else null } fun addLast(element:T){ backingList.add(element) } fun getLast():T?{ if (backingList.isEmpty()){ return null } val value = backingList.last() removeLast() return value } fun removeLast(){ if (backingList.isNotEmpty()) backingList.removeAt(backingList.size - 1) } fun peekLast():T?{ return if (backingList.isNotEmpty()) backingList.last() else null } } ================================================ FILE: Deque/DequeTest.kt ================================================ package deque import org.jetbrains.spek.api.Spek import org.junit.Assert.* /** * Spek BDD Test for Deque Class */ class DequeSpecs: Spek(spekBody = { given("Given an Empty Queue") { val deque: Deque = Deque() on("Peeking first value") { val value = deque.getFirst() it("should result in null value") { assertNull(value) } } on("Peeking last value"){ val value = deque.getLast() it("should result in a null value"){ assertNull(value) } } } given("Given a Queue with 1 value") { val deque: Deque = Deque() deque.addFirst(1) on("Fetching first value") { val value = deque.getFirst() it("1. should not result in null value") { assertNotNull(value) assertEquals(1, value) } it("2. should have removed the final value"){ assertNull(deque.peekFirst()) } } } given("Given a Queue with 1 value") { val deque: Deque = Deque() deque.addFirst(1) on("Fetching last value") { val value = deque.getLast() it("1. should not result in null value") { assertNotNull(value) assertEquals(1, value) } it("2. should have removed the final value"){ assertNull(deque.peekFirst()) } } } given("Given a Queue with 2 values") { val deque: Deque = Deque() deque.addFirst(2) deque.addFirst(1) on("Fetching first value") { val value = deque.peekFirst() it("should not result in null value") { assertNotNull(value) assertEquals(1, value) } } on("Fetching last value") { val value = deque.peekLast() it("should not result in null value") { assertNotNull(value) assertEquals(2, value) } } on("Removing last value") { deque.removeLast() it("There should be 1 value left on the queue") { val value = deque.peekFirst() assertNotNull(value) assertEquals(1, value) } } } }) ================================================ FILE: Deque/README.markdown ================================================ # Dequeue In computer science, a double-ended queue (dequeue, often abbreviated to deque, pronounced deck) is an abstract data type that generalizes a queue, for which elements can be added to or removed from either the front (head) or back (tail).[1] It is also often called a head-tail linked list, though properly this refers to a specific data structure implementation source:Wikipedia ## The code ```kotlin class Deque(){ var backingList : MutableList = arrayListOf() fun addFirst(element:T){ backingList.add(0,element) } fun getFirst():T?{ if (backingList.isEmpty()){ return null } val value = backingList.first() removeFirst() return value } fun removeFirst(){ if (backingList.isNotEmpty()) backingList.removeAt(0) } fun peekFirst(): T?{ return if (backingList.isNotEmpty()) backingList.first() else null } fun addLast(element:T){ backingList.add(element) } fun getLast():T?{ if (backingList.isEmpty()){ return null } val value = backingList.last() removeLast() return value } fun removeLast(){ if (backingList.isNotEmpty()) backingList.removeAt(backingList.size - 1) } fun peekLast():T?{ return if (backingList.isNotEmpty()) backingList.last() else null } } ``` Code by: - [Andy Bowes](https://github.com/AndyBowes) ================================================ FILE: InsertionSort/InsertionSort.kt ================================================ /** * Created by gazollajunior on 09/04/16. */ fun > insertionsort(items:MutableList):List{ if (items.isEmpty()){ return items } for (count in 1..items.count() - 1){ val item = items[count] var i = count while (i>0 && item < items[i - 1]){ items[i] = items[i - 1] i -= 1 } items[i] = item } return items } fun main(args: Array) { val names = mutableListOf("John", "Tim", "Zack", "Daniel", "Adam") println(names) var ordered = insertionsort(names) println(ordered) } ================================================ FILE: InsertionSort/README.markdown ================================================ # Insertion sort Insertion sort is a simple sorting algorithm that builds the final sorted array (or list) one item at a time. It is much less efficient on large lists than more advanced algorithms such as quicksort, heapsort, or merge sort. source:Wikipedia ## The code ```kotlin fun > insertionsort(items:MutableList):List{ if (items.isEmpty()){ return items } for (count in 1..items.count() - 1){ val item = items[count] var i = count while (i>0 && item < items[i - 1]){ items[i] = items[i - 1] i -= 1 } items[i] = item } return items } ``` ================================================ FILE: LinearSearch/LinearSearch.kt ================================================ /** * Created by gazollajunior on 05/04/16. */ fun >linearSearch(list:List, key:T):Int?{ for ((index, value) in list.withIndex()) { if (value == key) return index } return null } fun main(args: Array) { println("\nOrdered list:") val ordered = listOf("Adam", "Clark", "John", "Tim", "Zack") println(ordered) val name = "John" val position = linearSearch(ordered, name) println("\n${name} is in the position ${position} in the ordered List.") } ================================================ FILE: LinearSearch/README.markdown ================================================ # Linear Search Linear search is the simplest search algorithm; it is a special case of brute-force search. Its worst case cost is proportional to the number of elements in the list. Its expected cost is also proportional to the number of elements if all elements are searched equally. If the list has more than a few elements and is searched often, then more complicated search methods such as binary search or hashing may be appropriate. Those methods have faster search times but require additional resources to attain that speed. source:Wikipedia ## The code ```kotlin fun >linearSearch(list:List, key:T):Int?{ for ((index, value) in list.withIndex()) { if (value == key) return index } return null } ``` ================================================ FILE: LinkedList/LinkedList.kt ================================================ /** * Created by gazollajunior on 07/04/16. */ class Node(value: T){ var value:T = value var next: Node? = null var previous:Node? = null } class LinkedList { private var head:Node? = null var isEmpty:Boolean = head == null fun first():Node? = head fun last(): Node? { var node = head if (node != null){ while (node?.next != null) { node = node?.next } return node } else { return null } } fun count():Int { var node = head if (node != null){ var counter = 1 while (node?.next != null){ node = node?.next counter += 1 } return counter } else { return 0 } } fun nodeAtIndex(index: Int) : Node? { if (index >= 0) { var node = head var i = index while (node != null) { if (i == 0) return node i -= 1 node = node.next } } return null } fun append(value: T) { var newNode = Node(value) var lastNode = this.last() if (lastNode != null) { newNode.previous = lastNode lastNode.next = newNode } else { head = newNode } } fun removeAll() { head = null } fun removeNode(node: Node):T { val prev = node.previous val next = node.next if (prev != null) { prev.next = next } else { head = next } next?.previous = prev node.previous = null node.next = null return node.value } fun removeLast() : T? { val last = this.last() if (last != null) { return removeNode(last) } else { return null } } fun removeAtIndex(index: Int):T? { val node = nodeAtIndex(index) if (node != null) { return removeNode(node) } else { return null } } override fun toString(): String { var s = "[" var node = head while (node != null) { s += "${node.value}" node = node.next if (node != null) { s += ", " } } return s + "]" } } fun main(args: Array) { var ll = LinkedList() ll.append("John") println(ll) ll.append("Carl") println(ll) ll.append("Zack") println(ll) ll.append("Tim") println(ll) ll.append("Steve") println(ll) ll.append("Peter") println(ll) print("\n\n") println("first item: ${ll.first()?.value}") println("last item: ${ll.last()?.value}") println("second item: ${ll.first()?.next?.value}") println("penultimate item: ${ll.last()?.previous?.value}") println("\n4th item: ${ll.nodeAtIndex(3)?.value}") println("\nthe list has ${ll.count()} items") } ================================================ FILE: LinkedList/README.markdown ================================================ # Linked List A linked list is a linear collection of data elements, called nodes pointing to the next node by means of a pointer. It is a data structure consisting of a group of nodes which together represent a sequence. Under the simplest form, each node is composed of data and a reference (in other words, a link) to the next node in the sequence; more complex variants add additional links. This structure allows for efficient insertion or removal of elements from any position in the sequence. source:Wikipedia ## The Node ```kotlin class Node(value: T){ var value:T = value var next: Node? = null var previous:Node? = null } ``` ## The Linked List ```kotlin class LinkedList { private var head:Node? = null var isEmpty:Boolean = head == null fun first():Node? = head fun last(): Node? { var node = head if (node != null){ while (node?.next != null) { node = node?.next } return node } else { return null } } fun count():Int { var node = head if (node != null){ var counter = 1 while (node?.next != null){ node = node?.next counter += 1 } return counter } else { return 0 } } fun nodeAtIndex(index: Int) : Node? { if (index >= 0) { var node = head var i = index while (node != null) { if (i == 0) return node i -= 1 node = node.next } } return null } fun append(value: T) { var newNode = Node(value) var lastNode = this.last() if (lastNode != null) { newNode.previous = lastNode lastNode.next = newNode } else { head = newNode } } fun removeAll() { head = null } fun removeNode(node: Node):T { val prev = node.previous val next = node.next if (prev != null) { prev.next = next } else { head = next } next?.previous = prev node.previous = null node.next = null return node.value } fun removeLast() : T? { val last = this.last() if (last != null) { return removeNode(last) } else { return null } } fun removeAtIndex(index: Int):T? { val node = nodeAtIndex(index) if (node != null) { return removeNode(node) } else { return null } } override fun toString(): String { var s = "[" var node = head while (node != null) { s += "${node.value}" node = node.next if (node != null) { s += ", " } } return s + "]" } } ``` ================================================ FILE: MergeSort/MergeSort.kt ================================================ /** * Created by gazollajunior on 09/04/16. */ fun >mergesort(items:MutableList):MutableList{ if (items.isEmpty()){ return items } fun merge(left:MutableList, right:MutableList):MutableList{ var merged: MutableList = arrayListOf() while(!left.isEmpty() && !right.isEmpty()){ val temp:T if (left.first() < right.first()) { temp = left.removeAt(0) } else { temp = right.removeAt(0) } merged.add(temp) } if (!left.isEmpty()) merged.addAll(left) if (!right.isEmpty()) merged.addAll(right) return merged } val pivot = items.count()/2 var left = mergesort(items.subList(0, pivot)) var right = mergesort(items.subList(pivot, items.count()-1)) return merge(left, right) } fun main(args: Array) { val names = mutableListOf("John", "Tim", "Zack", "Daniel", "Adam") println(names) var ordered = mergesort(names) println(ordered) } ================================================ FILE: MergeSort/README.markdown ================================================ # MergeSort Merge Sort is an efficient, general-purpose, comparison-based sorting algorithm. Most implementations produce a stable sort, which means that the implementation preserves the input order of equal elements in the sorted output. Mergesort is a divide and conquer algorithm that was invented by John von Neumann in 1945. source:Wikipedia ## The code ```kotlin fun >mergesort(items:MutableList):MutableList{ if (items.isEmpty()){ return items } fun merge(left:MutableList, right:MutableList):MutableList{ var merged: MutableList = arrayListOf() while(!left.isEmpty() && !right.isEmpty()){ val temp:T if (left.first() < right.first()) { temp = left.removeAt(0) } else { temp = right.removeAt(0) } merged.add(temp) } if (!left.isEmpty()) merged.addAll(left) if (!right.isEmpty()) merged.addAll(right) return merged } val pivot = items.count()/2 var left = mergesort(items.subList(0, pivot)) var right = mergesort(items.subList(pivot, items.count()-1)) return merge(left, right) } ``` ================================================ FILE: OrderedArray/OrderedArray.kt ================================================ /** * Created by gazollajunior on 02/04/16. */ class OrderedArray>(list:MutableList){ var items: MutableList = this.quicksort(list) as MutableList /** * Use quicksort algorithm to order elements in array */ fun quicksort(its:List):List{ if (its.count() < 1) return its val pivot = its[its.count()/2] val equal = its.filter { it == pivot } val less = its.filter { it < pivot } val greater = its.filter { it > pivot } return quicksort(less) + equal + quicksort(greater) } fun insert(element:T){ val position = findElementPosition(element) this.items.add(position, element) } /** * Use binarySearch algorithm to find the position for the new element in array */ fun findElementPosition(element:T):Int{ var rangeStart = 0 var rangeEnd = this.items.count() while (rangeStart < rangeEnd) { val midIndex = rangeStart + (rangeEnd - rangeStart)/2 if (this.items[midIndex] == element) { return midIndex } else if (this.items[midIndex] < element){ rangeStart = midIndex + 1 } else { rangeEnd = midIndex } } return rangeStart } override fun toString():String = this.items.toString() } fun main(args: Array) { println("\nOriginal list:") val names = listOf("Tim", "Steve", "Zack", "Adam", "John", "Peter", "Clark") as MutableList println(names) println("\nOrdered list:") val ordered = OrderedArray(names) println(ordered) val n1 = "Paul" println("\nAdding ${n1} to the list:") ordered.insert(n1) println(ordered) val n2 = "Demetrius" println("\nAdding ${n2} to the list:") ordered.insert(n2) println(ordered) } ================================================ FILE: OrderedArray/README.markdown ================================================ # Ordered Array A sorted array is an array data structure in which each element is sorted in numerical, alphabetical, or some other order, and placed at equally spaced addresses in computer memory. It is typically used in computer science to implement static lookup tables to hold multiple values which have the same data type. Sorting a stack of baby unicorns of different ages is useful in organising data in ordered form and recovering them rapidly. The implementation is quite basic: ```kotlin class OrderedArray>(list:MutableList){ var items: MutableList = this.quicksort(list) as MutableList /** * Use quicksort algorithm to order elements in array */ fun quicksort(its:List):List{ if (its.count() < 1) return its val pivot = its[its.count()/2] val equal = its.filter { it == pivot } val less = its.filter { it < pivot } val greater = its.filter { it > pivot } return quicksort(less) + equal + quicksort(greater) } fun insert(element:T){ val position = findElementPosition(element) this.items.add(position, element) } /** * Use binarySearch algorithm to find the position for the new element in array */ fun findElementPosition(element:T):Int{ var rangeStart = 0 var rangeEnd = this.items.count() while (rangeStart < rangeEnd) { val midIndex = rangeStart + (rangeEnd - rangeStart)/2 if (this.items[midIndex] == element) { return midIndex } else if (this.items[midIndex] < element){ rangeStart = midIndex + 1 } else { rangeEnd = midIndex } } return rangeStart } override fun toString():String = this.items.toString() } ``` ================================================ FILE: OrderedSet/OrderedSet.kt ================================================ /** * Created by gazollajunior on 08/04/16. */ class OrderedSet>(list:MutableList){ var items: MutableList = list fun insert(element:T) { if (exists(element)) { return } for (i in 0..this.items.count() - 1){ if (this.items[i] > element){ this.items.add(i, element) return } } this.items.add(element) } /** * Use binarySearch algorithm to find the position for the new element in array */ fun findElementPosition(element:T):Int?{ var rangeStart = 0 var rangeEnd = this.items.count() while (rangeStart < rangeEnd) { val midIndex = rangeStart + (rangeEnd - rangeStart)/2 if (this.items[midIndex] == element) { return midIndex } else if (this.items[midIndex] < element){ rangeStart = midIndex + 1 } else { rangeEnd = midIndex } } return null } override fun toString():String = this.items.toString() fun isEmpty():Boolean = this.items.isEmpty() fun exists(element:T):Boolean = findElementPosition(element) != null fun count():Int = this.items.count() fun remove(element:T) { val position = findElementPosition(element) if (position != null) { this.items.removeAt(position) } } fun removeAll() = this.items.removeAll(this.items) fun max():T? { if (count() != 0) { return this.items[count() - 1] } else { return null } } fun min():T? { if (count() != 0) { return this.items[0] } else { return null } } } fun main(args: Array) { println("\nOriginal set:") val names = mutableListOf("Demetrius") var nameSet = OrderedSet(names) println(nameSet) val n1 = "Adam" println("\nAdding ${n1} to the list:") nameSet.insert(n1) println(nameSet) val n2 = "Tim" println("\nAdding ${n2} to the list:") nameSet.insert(n2) println(nameSet) val n3 = "Zack" println("\nAdding ${n3} to the list:") nameSet.insert(n3) println(nameSet) val n4 = "Zack" println("\nTry Add ${n4} again to the list:") nameSet.insert(n4) println(nameSet) nameSet.remove(n2) println("\nRemoving ${n2} from the list:") println(nameSet) nameSet.remove(n4) println("\nRemoving ${n4} from the list:") println(nameSet) nameSet.remove(n1) println("\nRemoving ${n1} from the list:") println(nameSet) } ================================================ FILE: OrderedSet/README.markdown ================================================ # Ordered Set An ordered set is a common data structure that supports O(log N) lookups, insertions and removals. Ordered set is also sometimes used as an alternative to a hash map, for example in STL’s map. ## The code ```kotlin class OrderedSet>(list:MutableList){ var items: MutableList = list fun insert(element:T) { if (exists(element)) { return } for (i in 0..this.items.count() - 1){ if (this.items[i] > element){ this.items.add(i, element) return } } this.items.add(element) } /** * Use binarySearch algorithm to find the position for the new element in array */ fun findElementPosition(element:T):Int?{ var rangeStart = 0 var rangeEnd = this.items.count() while (rangeStart < rangeEnd) { val midIndex = rangeStart + (rangeEnd - rangeStart)/2 if (this.items[midIndex] == element) { return midIndex } else if (this.items[midIndex] < element){ rangeStart = midIndex + 1 } else { rangeEnd = midIndex } } return null } override fun toString():String = this.items.toString() fun isEmpty():Boolean = this.items.isEmpty() fun exists(element:T):Boolean = findElementPosition(element) != null fun count():Int = this.items.count() fun remove(element:T) { val position = findElementPosition(element) if (position != null) { this.items.removeAt(position) } } fun removeAll() = this.items.removeAll(this.items) fun max():T? { if (count() != 0) { return this.items[count() - 1] } else { return null } } fun min():T? { if (count() != 0) { return this.items[0] } else { return null } } } ``` ================================================ FILE: Queue/Queue.kt ================================================ /** * Created by gazollajunior on 05/04/16. */ class Queue (list:MutableList): Iterator{ var itCounter: Int = 0 var items:MutableList = list fun isEmpty():Boolean = this.items.isEmpty() fun count():Int = this.items.count() override fun toString() = this.items.toString() fun enqueue(element: T){ this.items.add(element) } fun dequeue():T?{ if (this.isEmpty()){ return null } else { return this.items.removeAt(0) } } fun peek():T?{ return this.items[0] } override fun hasNext(): Boolean { val hasNext = itCounter < count() // As soon as condition fails, reset the counter if (!hasNext) itCounter = 0 return hasNext } override fun next(): T { if (hasNext()) { val topPos: Int = (count() - 1) - itCounter itCounter++ return this.items[topPos] } else { throw NoSuchElementException("No such element") } } } fun main(args: Array) { var initialValue = mutableListOf(10) var queue = Queue(initialValue) println(queue) queue.enqueue(22) println(queue) queue.enqueue(55) println(queue) queue.enqueue(77) println(queue) queue.dequeue() println(queue) queue.dequeue() println(queue) queue.dequeue() println(queue) // Iterating over queue for (item in queue) println("Item in queue : " + item) } ================================================ FILE: Queue/README.markdown ================================================ # Queue Queue is a particular kind of abstract data type or collection in which the entities in the collection are kept in order and the principal (or only) operations on the collection are the addition of entities to the rear terminal position, known as enqueue, and removal of entities from the front terminal position, known as dequeue. This makes the queue a First-In-First-Out (FIFO) data structure. In a FIFO data structure, the first element added to the queue will be the first one to be removed. This is equivalent to the requirement that once a new element is added, all elements that were added before have to be removed before the new element can be removed. Often a peek or front operation is also entered, returning the value of the front element without dequeuing it. A queue is an example of a linear data structure, or more abstractly a sequential collection. source:Wikipedia ![](https://github.com/gazolla/Kotlin-Algorithm/blob/master/Queue/Queue.png) ## The code ```kotlin class Queue (list:MutableList){ var items:MutableList = list fun isEmpty():Boolean = this.items.isEmpty() fun count():Int = this.items.count() override fun toString() = this.items.toString() fun enqueue(element: T){ this.items.add(element) } fun dequeue():T?{ if (this.isEmpty()){ return null } else { return this.items.removeAt(0) } } fun peek():T?{ return this.items[0] } } ``` ================================================ FILE: QuickSort/QuickSort.kt ================================================ /** * Created by gazollajunior on 01/04/16. */ fun >quicksort(items:List):List{ if (items.count() < 2){ return items } val pivot = items[items.count()/2] val equal = items.filter { it == pivot } val less = items.filter { it < pivot } val greater = items.filter { it > pivot } return quicksort(less) + equal + quicksort(greater) } fun main(args: Array) { println("\nOriginal list:") val names = listOf("Tim", "Steve", "Zack", "Adam", "John", "Peter", "Clark") println(names) println("\nOrdered list:") val ordered = quicksort(names) println(ordered) } ================================================ FILE: QuickSort/README.markdown ================================================ # Quicksort Quicksort is an efficient sorting algorithm, serving as a systematic method for placing the elements of an array in order. Developed by Tony Hoare in 1959, with his work published in 1961, it is still a commonly used algorithm for sorting. When implemented well, it can be about two or three times faster than its main competitors, merge sort and heapsort. Here's an implementation in kotlin that should be easy to understand: ```kotlin fun >quicksort(items:List):List{ if (items.count() < 1) return items val pivot = items[items.count()/2] val equal = items.filter { it == pivot } val less = items.filter { it < pivot } val greater = items.filter { it > pivot } return quicksort(less) + equal + quicksort(greater) } ``` ================================================ FILE: README.markdown ================================================ # Welcome to Kotlin Algorithms Here you'll find implementations of popular algorithms and data structures in [Kotlin programming language](https://kotlinlang.org/). This is a work in progress. More algorithms will be added soon. :-) **Suggestions and contributions are welcome!** ## The algorithms ### Searching - [Linear Search](LinearSearch/) - [Binary Search](BinarySearch/) - [Count Occurrences] - [Select Minimum / Maximum] - [k-th Largest Element] - [Selection Sampling] - [Union-Find] - [Depth-First Search](DepthFirstSearch/) ### String Search - [Brute-Force String Search] - [Boyer-Moore] - Rabin-Karp - [Longest Common Subsequence] ### Sorting Basic sorts: - [Insertion Sort](InsertionSort/) - [Selection Sort](SelectionSort/) - [Shell Sort](ShellSort/) Fast sorts: - [Quicksort](QuickSort/) - [Merge Sort](MergeSort/) - [Heap Sort] Special-purpose sorts: - Bucket Sort - Counting Sort - Radix Sort - [Topological Sort] ### Compression - [Run-Length Encoding (RLE)](Compression/) - [Huffman Coding] ### Miscellaneous - [Shuffle](Shuffle/) Randomly rearranges the contents of an array. ### Machine learning - [k-Means Clustering] - k-Nearest Neighbors - Linear Regression - Logistic Regression - Neural Networks - PageRank ## Data structures ### Variations on arrays - [Array2D] - [Bit Set] - [Fixed Size Array] - [Ordered Array](Ordered Array/) ### Queues - [Stack](Stack/) - [Queue](Queue/) - [Deque](Deque/) - [Priority Queue] - [Bounded Priority Queue] - [Ring Buffer] ### Lists - [Linked List](LinkedList/) - Skip List ### Trees - [Tree](Tree/) - [Binary Tree] - [Binary Search Tree (BST)] - [AVL Tree] - Red-Black Tree - Splay Tree - Threaded Binary Tree - [Segment Tree] - kd-Tree - [Heap] - Fibonacci Heap - Trie - [B-Tree] ### Hashing - [Hash Table] - Hash Functions ### Sets - [Bloom Filter] - [Hash Set] - Multiset - [Ordered Set](OrderedSet/) ### Graphs - [Graph] - [Breadth-First Search (BFS)] - [Depth-First Search (DFS)] - [Shortest Path] - [Minimum Spanning Tree] - All Paths ## License All content is licensed under the terms of the MIT open source license. ### Contributors * [Andy Bowes](https://github.com/AndyBowes) * [Niccolò Passolunghi](https://github.com/nicopasso) * [Vansh Gandhi](https://github.com/vanshg) * [Szabolcs Besenyei](https://github.com/besza) * [Markus Kramer](https://github.com/MarkusKramer) * [Luís Soares](https://github.com/lsoares) ### Contact * Sebastian Gazolla Jr * [@gazollajr](http://twitter.com/gazollajr) * [http://gazapps.com](http://gazapps.com) * [http://about.me/gazolla](http://about.me/gazolla) ================================================ FILE: SelectionSort/README.markdown ================================================ # Selection sort Selection sort is a sorting algorithm, specifically an in-place comparison sort. It has O(n2) time complexity, making it inefficient on large lists, and generally performs worse than the similar insertion sort. Selection sort is noted for its simplicity, and it has performance advantages over more complicated algorithms in certain situations, particularly where auxiliary memory is limited. source:Wikipedia ## The code ```kotlin fun >selectionsort(items:MutableList):MutableList{ if (items.isEmpty()){ return items } for (idx in 0..items.count()){ val array = items.subList(0,items.count()-idx) val minItem = array.min() val indexOfMinItem = array.indexOf(minItem) if (minItem != null) { items.removeAt(indexOfMinItem) items.add(minItem) } } return items } ``` ================================================ FILE: SelectionSort/SelectionSort.kt ================================================ /** * Created by gazollajunior on 09/04/16. */ fun >selectionsort(items:MutableList):MutableList{ if (items.isEmpty()){ return items } for (idx in 0..items.count()){ val array = items.subList(0,items.count()-idx) val minItem = array.min() val indexOfMinItem = array.indexOf(minItem) if (minItem != null) { items.removeAt(indexOfMinItem) items.add(minItem) } } return items } fun main(args: Array) { println("Selection Sort") val names = mutableListOf("John", "Tim", "Zack", "Daniel", "Adam") println(names) var ordered = insertionsort(names) println(ordered) } ================================================ FILE: ShellSort/README.markdown ================================================ # Shell Sort Shellsort, also known as Shell sort or Shell's method, is an in-place comparison sort. It can be seen as either a generalization of sorting by exchange (bubble sort) or sorting by insertion (insertion sort). The method starts by sorting pairs of elements far apart from each other, then progressively reducing the gap between elements to be compared. Starting with far apart elements, it can move some out-of-place elements into position faster than a simple nearest neighbor exchange. Donald Shell published the first version of this sort in 1959. The running time of Shellsort is heavily dependent on the gap sequence it uses. source: [Wikipedia ShellSort](https://en.wikipedia.org/wiki/Shellsort) ================================================ FILE: ShellSort/ShellSort.kt ================================================ fun MutableList.swap(index1: Int, index2: Int) { val tmp = this[index1] this[index1] = this[index2] this[index2] = tmp } fun MutableList.shellSort(): MutableList { var sublistCount = count() / 2 while (sublistCount > 0) { var index = 0 outer@while (index >= 0 && index < count()) { if (index + sublistCount >= count()) break if (this[index] > this[index + sublistCount]) { swap(index, index + sublistCount) } if (sublistCount == 1 && index > 0) { while (this[index - 1] > this[index] && index - 1 > 0) { swap(index - 1, index) index -= 1 } index++ } else { index++ continue@outer } } sublistCount /= 2 } return this } fun main(args: Array) { var mutableListOfInt = mutableListOf(10, 4, 5, 2, 1, 3, 6, 9, 8, 7) print(mutableListOfInt.shellSort().toString()) } ================================================ FILE: Shuffle/README.markdown ================================================ # Shuffle Randomly rearranges the contents of an array. ## The code Here is a implementation of Shuffle in kotlin: ```kotlin fun >shuffle(items:MutableList):List{ val rg : Random = Random() for (i in 0..items.size - 1) { val randomPosition = rg.nextInt(items.size) val tmp : T = items[i] items[i] = items[randomPosition] items[randomPosition] = tmp } return items } ``` Shuffle implementation provide by Markus Kramer. This implementation reuses existing code to do the shuffling and can be called like other kotlin collection functions. ```kotlin /** * Returns a randomized list. */ fun Iterable.shuffle(seed: Long? = null): List { val list = this.toMutableList() val random = if (seed != null) Random(seed) else Random() Collections.shuffle(list, random) return list } ``` ================================================ FILE: Shuffle/Shuffle.kt ================================================ /** * Created by gazollajunior on 03/04/16. */ import java.util.Random fun >shuffle(items:MutableList):List{ val rg : Random = Random() for (i in 0..items.size - 1) { val randomPosition = rg.nextInt(items.size) val tmp : T = items[i] items[i] = items[randomPosition] items[randomPosition] = tmp } return items } /* extension version */ fun Iterable.shuffle(): List { val list = this.toMutableList().apply { } Collections.shuffle(list) return list } fun main(args: Array) { println("\nOrdered list:") val ordered = listOf("Adam", "Clark", "John", "Tim", "Zack") println(ordered) println("\nshuffled list:") val shuffled = shuffle(ordered as MutableList) print(shuffled) val orderedB = listOf(1, 2, 3, 4, 5) print(orderedB.shuffle()) } ================================================ FILE: Stack/README.markdown ================================================ # Stack Stack is an abstract data type that serves as a collection of elements, with two principal operations: push, which adds an element to the collection, and pop, which removes the most recently added element that was not yet removed. The order in which elements come off a stack gives rise to its alternative name, LIFO (for last in, first out). Additionally, a peek operation may give access to the top without modifying the stack. ![](https://github.com/gazolla/Kotlin-Algorithm/blob/master/Stack/Lifo_stack.png) ## The code ```kotlin class Stack>(list:MutableList) { var items: MutableList = list fun isEmpty():Boolean = this.items.isEmpty() fun count():Int = this.items.count() fun push(element:T) { val position = this.count() this.items.add(position, element) } override fun toString() = this.items.toString() fun pop():T? { if (this.isEmpty()) { return null } else { val item = this.items.count() - 1 return this.items.removeAt(item) } } fun peek():T? { if (isEmpty()) { return null } else { return this.items[this.items.count() - 1] } } } ``` ================================================ FILE: Stack/Stack.kt ================================================ /** * Created by gazollajunior on 03/04/16. */ class Stack>(list:MutableList):Iterator { var itCounter: Int = 0 var items: MutableList = list fun isEmpty():Boolean = this.items.isEmpty() fun count():Int = this.items.count() fun push(element:T) { val position = this.count() this.items.add(position, element) } override fun toString() = this.items.toString() fun pop():T? { if (this.isEmpty()) { return null } else { val item = this.items.count() - 1 return this.items.removeAt(item) } } fun peek():T? { if (isEmpty()) { return null } else { return this.items[this.items.count() - 1] } } // Note Let the default implementation exist // override fun toString(): String { // val topDivider = "---Stack---\n" // val bottomDivider = "\n-----------" // // val stackElements = array.map { // "$it" // }.reversed().joinToString("\n") // // return topDivider + stackElements + bottomDivider // // } override fun hasNext(): Boolean { val hasNext = itCounter < count() // As soon as condition fails, reset the counter if (!hasNext) itCounter = 0 return hasNext } override fun next(): T { if (hasNext()) { val topPos: Int = (count() - 1) - itCounter itCounter++ return this.items[topPos] } else { throw NoSuchElementException("No such element") } } } fun main(args: Array) { var initialValue = mutableListOf(10) var stack = Stack(initialValue) println(stack) stack.push(22) println(stack) stack.push(55) println(stack) stack.push(77) println(stack) stack.pop() println(stack) for (item in stack) println("Item in stack : " + item) } ================================================ FILE: Tree/README.markdown ================================================ # Tree Tree is a widely used abstract data type (ADT)—or data structure implementing this ADT—that simulates a hierarchical tree structure, with a root value and subtrees of children with a parent node, represented as a set of linked nodes. A tree data structure can be defined recursively (locally) as a collection of nodes (starting at a root node), where each node is a data structure consisting of a value, together with a list of references to nodes (the "children"), with the constraints that no reference is duplicated, and none points to the root. source: Wikipedia ## The code ```kotlin class TreeNode(value:T){ var value:T = value var parent:TreeNode? = null var children:MutableList> = mutableListOf() fun addChild(node:TreeNode){ children.add(node) node.parent = this } override fun toString(): String { var s = "${value}" if (!children.isEmpty()) { s += " {" + children.map { it.toString() } + " }" } return s } } ``` ================================================ FILE: Tree/Tree.kt ================================================ /** * Created by gazolla on 10/04/16. */ class TreeNode(value:T){ var value:T = value var parent:TreeNode? = null var children:MutableList> = mutableListOf() fun addChild(node:TreeNode){ children.add(node) node.parent = this } override fun toString(): String { var s = "${value}" if (!children.isEmpty()) { s += " {" + children.map { it.toString() } + " }" } return s } } fun main(args: Array) { val tree = TreeNode( "beverages") val hotNode = TreeNode( "hot") val coldNode = TreeNode( "cold") val teaNode = TreeNode( "tea") val coffeeNode = TreeNode( "coffee") val chocolateNode = TreeNode( "cocoa") val blackTeaNode = TreeNode( "black") val greenTeaNode = TreeNode( "green") val chaiTeaNode = TreeNode( "chai") val sodaNode = TreeNode( "soda") val milkNode = TreeNode( "milk") val gingerAleNode = TreeNode( "ginger ale") val bitterLemonNode = TreeNode( "bitter lemon") tree.addChild(hotNode) tree.addChild(coldNode) hotNode.addChild(teaNode) hotNode.addChild(coffeeNode) hotNode.addChild(chocolateNode) coldNode.addChild(sodaNode) coldNode.addChild(milkNode) teaNode.addChild(blackTeaNode) teaNode.addChild(greenTeaNode) teaNode.addChild(chaiTeaNode) sodaNode.addChild(gingerAleNode) sodaNode.addChild(bitterLemonNode) println(tree) }