Go codePermalink

package main
import (
"fmt"
"math/rand"
"time"
)
const TEST_NUM = 10
const TEST_LIMIT = 50
func main() {
randNumList := GetRandomList()
fmt.Printf("Origianl List : \t")
printList(randNumList)
fmt.Printf("Bubble Sort : \t\t")
printList(BubbleSort(randNumList))
fmt.Printf("Selection Sort : \t")
printList(SelectionSort(randNumList))
fmt.Printf("Insertion Sort : \t")
printList(InsertionSort(randNumList))
fmt.Printf("Shell Sort : \t\t")
printList(ShellSort(randNumList))
fmt.Printf("Quick Sort : \t\t")
printList(QuickSort(randNumList))
fmt.Printf("Heap Sort : \t\t")
printList(HeapSort(randNumList))
fmt.Printf("Merge Sort : \t\t")
printList(MergeSort(randNumList))
fmt.Printf("Radix Sort : \t\t")
printList(RadixSort(randNumList))
}
func GetRandomList() []int {
result := []int{}
cashMap := map[int]bool{}
src := rand.NewSource(time.Now().UTC().UnixNano())
r := rand.New(src)
for i := 0; i < TEST_NUM; i++ {
randNum := r.Intn(TEST_LIMIT)
if cashMap[randNum] {
// loop again
i--
continue
}
cashMap[randNum] = true
result = append(result, randNum)
}
return result
}
func printList(numList []int) {
for i := 0; i < len(numList); i++ {
fmt.Printf("%d\t", numList[i])
}
fmt.Printf("\n")
}
func deepCopyList(numList []int) []int {
result := make([]int, len(numList))
copy(result, numList)
return result
}
// time : O(n²)
func BubbleSort(numList []int) []int {
result := deepCopyList(numList)
for i := 0; i < len(result)-1; i++ {
for j := 0; j < len(result); j++ {
if j+1 < len(result) && result[j] > result[j+1] {
swap(result, j, j+1)
}
}
}
return result
}
// time : O(n²)
func SelectionSort(numList []int) []int {
result := deepCopyList(numList)
for i := 0; i < len(result)-1; i++ {
min := result[i]
minIndex := i
for j := i + 1; j < len(result); j++ {
if result[j] < min {
min = result[j]
minIndex = j
}
}
if minIndex > i {
swap(result, i, minIndex)
}
}
return result
}
// time : O(n²)
func InsertionSort(numList []int) []int {
result := deepCopyList(numList)
for i := 1; i < len(result); i++ {
curVal := result[i]
var j int
for j = i - 1; j >= 0 && curVal < result[j]; j-- {
// move next
result[j+1] = result[j]
}
result[j+1] = curVal
}
return result
}
// time : O(n²)
func ShellSort(numList []int) []int {
result := deepCopyList(numList)
interval := int(float32(len(result)) * 0.5)
for interval > 0 {
for i := 0; i < len(result); i++ {
intervalSort(result, i, len(result)-i, interval)
}
interval = int(float32(interval) * 0.5)
}
return result
}
func intervalSort(numList []int, start, end, interval int) {
for i := start + interval; i < end; i += interval {
curVal := numList[i]
var j int
for j = i - interval; j >= start && curVal < numList[j]; j -= interval {
numList[j+interval] = numList[j]
}
numList[j+interval] = curVal
}
}
// time : O(n²)
func QuickSort(numList []int) []int {
result := deepCopyList(numList)
qSort(result, 0, len(numList)-1)
return result
}
func qSort(numList []int, start, end int) {
if start >= end {
return
}
middle := start + int(float32(end-start)*0.5)
pivot := numList[middle]
left := start
right := end
for left <= right {
for numList[left] < pivot {
left++
}
for numList[right] > pivot {
right--
}
if left <= right {
// swap
swap(numList, left, right)
left++
right--
}
}
if start < right {
qSort(numList, start, right)
}
if end > left {
qSort(numList, left, end)
}
}
// time : O(nlogn)
func HeapSort(numList []int) []int {
result := deepCopyList(numList)
// rearrange heap
for i := int(float32(len(result))*0.5 - 1); i >= 0; i-- {
heapify(result, len(result), i)
}
for i := len(result) - 1; i >= 0; i-- {
// move current root to end
swap(result, 0, i)
// call max heapify on the reduced heap
heapify(result, i, 0)
}
return result
}
func heapify(numList []int, heapSize, rootIndex int) {
newRoot := rootIndex
left := rootIndex * 2
right := rootIndex*2 + 1
if left < heapSize && numList[left] > numList[newRoot] {
newRoot = left
}
if right < heapSize && numList[right] > numList[newRoot] {
newRoot = right
}
if newRoot != rootIndex {
swap(numList, rootIndex, newRoot)
// recursice for subtree
heapify(numList, heapSize, newRoot)
}
}
// 2-way merge
// time : O(nlogn)
func MergeSort(numList []int) []int {
result := deepCopyList(numList)
return mSort(result)
}
func mSort(numList []int) []int {
if len(numList) < 2 {
return numList
}
halfIndex := int(float32(len(numList)) * 0.5)
first := mSort(numList[:halfIndex])
second := mSort(numList[halfIndex:])
return merge(first, second)
}
func merge(first, second []int) []int {
result := []int{}
i := 0
j := 0
for i < len(first) && j < len(second) {
if first[i] < second[j] {
result = append(result, first[i])
i++
} else {
result = append(result, second[j])
j++
}
}
for ; i < len(first); i++ {
result = append(result, first[i])
}
for ; j < len(second); j++ {
result = append(result, second[j])
}
return result
}
// time : O(nlogn)
func RadixSort(numList []int) []int {
result := deepCopyList(numList)
largest := getLargestNum(result)
size := len(numList)
significantDigit := 1
semiSorted := make([]int, size, size)
for largest/significantDigit > 0 {
bucket := [10]int{0}
for i := 0; i < size; i++ {
bucket[(numList[i]/significantDigit)%10]++
}
for i := 1; i < 10; i++ {
bucket[i] += bucket[i-1]
}
for i := size - 1; i >= 0; i-- {
key := (numList[i] / significantDigit) % 10
bucket[key]--
semiSorted[bucket[key]] = numList[i]
}
for i := 0; i < size; i++ {
numList[i] = semiSorted[i]
}
significantDigit *= 10
}
return semiSorted
}
func getLargestNum(numList []int) int {
max := 0
for _, v := range numList {
if v > max {
max = v
}
}
return max
}
func swap(numList []int, i, j int) {
temp := numList[i]
numList[i] = numList[j]
numList[j] = temp
}
view raw 8sorts.go hosted with ❤ by GitHub

outputPermalink

Origianl List : 	13	20	22	31	21	43	25	35	1	17	
Bubble Sort : 		1	13	17	20	21	22	25	31	35	43	
Selection Sort : 	1	13	17	20	21	22	25	31	35	43	
Insertion Sort : 	1	13	17	20	21	22	25	31	35	43	
Shell Sort : 		1	13	17	20	21	22	25	31	35	43	
Quick Sort : 		1	13	17	20	21	22	25	31	35	43	
Heap Sort : 		1	13	17	20	21	22	25	31	35	43	
Merge Sort : 		1	13	17	20	21	22	25	31	35	43	
Radix Sort : 		1	13	17	20	21	22	25	31	35	43

Updated: