The Full Counting Sort

  • + 0 comments

    Kotlin code with some details which helped me understand the logic.

    fun countSort(arr: Array<Array<String>>): Unit {
        // Find the min and max values of the associated integers.
        //
        // Will be min=0 max=6 from the sample input.
        var min = Int.MAX_VALUE
        var max = Int.MIN_VALUE
        arr.forEach {
            val num = Integer.parseInt(it[0])
            if (num < min) min = num
            if (num > max) max = num
        }
        
        // Create a count array for counting occurrences of each
        // associated integer.
        // Note associated integers might not be 0-indexed so
    	// work out minimum number of spaces required.
        //
        // From the sample: max - min + 1 = 6 - 0 + 1 = 7
        // An array of 7 items will fit each value count (0-6).
        val countArray = IntArray(max - min + 1)
        
        // Go through the input array and count how many occurrences
        // of each associated integer there are.
        //
        // From the sample this is:
    	// 0=6, 1=2, 2=2, 3=1, 4=4, 5=1, 6=4
        arr.forEach { 
            val num = Integer.parseInt(it[0])
            countArray[num - min]++        
        }
        
        // Now update the count array to have running totals from left
        // to right.
        //
        // So add the first count to the second, the first 2 counts to
        // the third, and so on...
        //
        // From the sample this is:
        // 0=6, 1=8, 2=10, 3=11, 4=15, 5=16, 6=20
        for (index in 1 until countArray.size) {
            countArray[index] += countArray[index - 1]
        }
        
        // Create the output array. Note it's the same size as the
    	// input.
        // Fill with dashes by default to save filling them later.
        val output = Array<String>(arr.size) { "-" }
        
        // This is where everything comes together.
        //
        // Loop the input array from the end to the middle. 
        // Start at the end to ensure order is retained (stability).
        // Finish in the middle as we're told to have dashes for the
        // first half.
        for (index in arr.size - 1 downTo arr.size / 2) {
            // Get the associated integer for the item.
            val num = Integer.parseInt(arr[index][0])
            
            // Calculate where the item goes in the output array.
            // This is done by looking in the countArray.
            //
            // Taking the sample input, the last item is [4, "the"].
            // So 4 - 0 - 1 = 3
            // countArray[3] is 11 (see above).
            val pos = countArray[num - min] - 1
            
            // Set position in the output array to the value.
            // Following the example [4, "the"] this will set position
            // 11 in the output array to "the".
            output[pos] = arr[index][1]
            
            // Decrease the count of the associated integer so next 
            // time the value is place in the correct place as we're
            // working backwards.
            countArray[num - min]--
        }
        
        // Print out the output array.
        output.forEach { 
            print("$it ")
        }
        println("")
    }