From c565b5a684546cdf3f0e5a8c5ac304e64bb25a0d Mon Sep 17 00:00:00 2001 From: agung Date: Thu, 11 Dec 2014 12:47:12 +0700 Subject: [PATCH] Added QuickSort, HeapSort, CombSort --- Combsort.go | 90 +++++++++++++++++++++++++++++++++++++++++++++ Heapsort.go | 88 ++++++++++++++++++++++++++++++++++++++++++++ Quicksort.go | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 3 +- 4 files changed, 281 insertions(+), 1 deletion(-) create mode 100644 Combsort.go create mode 100644 Heapsort.go create mode 100644 Quicksort.go diff --git a/Combsort.go b/Combsort.go new file mode 100644 index 0000000..2f27db4 --- /dev/null +++ b/Combsort.go @@ -0,0 +1,90 @@ +package main + +import ( + "fmt" + "math/rand" + "time" +) + +type Interface interface { + Len() int + Swap(i, j int) + Less(i, j int) bool +} + +//O(n^2) +//fungsi untuk mengsort dengan comb sort +func Combsort(data Interface) { + if data.Len() < 2 { + return + } + for gap := data.Len(); ; { + if gap > 1 { + gap = gap * 4 / 5 + } + swapped := false + for i := 0; ; { + if data.Less(i+gap, i) { + data.Swap(i, i+gap) + swapped = true + } + i++ + if i+gap >= data.Len() { + break + } + } + if gap == 1 && !swapped { + break + } + } +} + +type SliceOfInt []int + +type SliceOfString []string + +//fungsi Len, Swap, dan Less untuk SliceOfInt dan SliceOfString +func (a SliceOfInt) Len() int { return len(a) } +func (a SliceOfInt) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a SliceOfInt) Less(i, j int) bool { return a[i] < a[j] } +func (a SliceOfString) Less(i, j int) bool { return a[i] < a[j] } +func (a SliceOfString) Len() int { return len(a) } +func (a SliceOfString) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + +func main() { + rand.Seed(time.Now().Unix()) + x := make(SliceOfInt, 10) + for i := 0; i < 10; i++ { + x[i] = rand.Intn(20) + } + fmt.Print("Before: ") + for i := 0; i < 10; i++ { + fmt.Print(x[i], " ") + } + fmt.Println() + sort(x) + fmt.Print("After: ") + for i := 0; i < 10; i++ { + fmt.Print(x[i], " ") + } + fmt.Println() + + y := make(SliceOfString, 3) + + fmt.Print("Before: ") + y[0] = "Ruby" + y[1] = "Emerald" + y[2] = "Sapphire" + for i := 0; i < 3; i++ { + fmt.Print(y[i], " ") + } + + fmt.Println() + Combsort(y) + fmt.Print("After: ") + for i := 0; i < 3; i++ { + fmt.Print(y[i], " ") + } + fmt.Println() + +} diff --git a/Heapsort.go b/Heapsort.go new file mode 100644 index 0000000..812771e --- /dev/null +++ b/Heapsort.go @@ -0,0 +1,88 @@ +package main + +import ( + "fmt" + "math/rand" + "time" +) + +type Interface interface { + Len() int + Swap(i, j int) + Less(i, j int) bool +} + +//O(len-1) +//Fungsi untuk melakukan sort menggunakan heapsort +func Heapsort(a Interface) { + for start := (a.Len() - 2) / 2; start >= 0; start-- { + check(a, start, a.Len()-1) + } + for end := a.Len() - 1; end > 0; end-- { + a.Swap(0, end) + Check(a, 0, end-1) + } +} + +//O(len-2) +//Fungsi untuk memindahkan kebelakang +func Check(a Interface, start, end int) { + for root := start; root*2+1 <= end; { + child := root*2 + 1 + if child+1 <= end && a.Less(child, child+1) { + child++ + } + if !a.Less(root, child) { + return + } + a.Swap(root, child) + root = child + } +} + +type SliceOfInt []int +type SliceOfString []string + +func (a SliceOfInt) Len() int { return len(a) } +func (a SliceOfInt) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a SliceOfInt) Less(i, j int) bool { return a[i] < a[j] } +func (a SliceOfString) Len() int { return len(a) } +func (a SliceOfString) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a SliceOfString) Less(i, j int) bool { return a[i] < a[j] } + +func main() { + a := make(SliceOfInt, 10) + fmt.Println() + fmt.Print("Before: ") + for i := 0; i < 10; i++ { + a[i] = rand.Intn(20) + fmt.Print(a[i], " ") + } + Heapsort(a) + fmt.Println() + fmt.Print("After: ") + for i := 0; i < 10; i++ { + fmt.Print(a[i], " ") + } + fmt.Println() + fmt.Println() + + y := make(SliceOfString, 3) + + fmt.Print("Before: ") + y[0] = "Ruby" + y[1] = "Emerald" + y[2] = "Sapphire" + for i := 0; i < 3; i++ { + fmt.Print(y[i], " ") + } + + fmt.Println() + Heapsort(y) + fmt.Print("After: ") + for i := 0; i < 3; i++ { + fmt.Print(y[i], " ") + } + fmt.Println() + +} diff --git a/Quicksort.go b/Quicksort.go new file mode 100644 index 0000000..c8f1597 --- /dev/null +++ b/Quicksort.go @@ -0,0 +1,101 @@ +package main + +import ( + "fmt" + "math/rand" + "time" +) + +type Interface interface { + Len() int + Swap(i, j int) + Less(i, j int) bool +} + +//O(n/2^n/2) +//Fungsi untuk memisahkan antara kiri dan kanan pivot +func partition(a Interface, first int, last int, pivotIndex int) int { + a.Swap(first, pivotIndex) + left := first + 1 + right := last + for left <= right { + for left <= last && a.Less(left, first) { + left++ + } + for right >= first && a.Less(first, right) { + right-- + } + if left <= right { + a.Swap(left, right) + left++ + right-- + } + } + a.Swap(first, right) + return right +} + +//O(1) +//Fungsi untuk menentukan pivot +func quicksortHelper(a Interface, first int, last int) { + if first >= last { + return + } + pivotIndex := partition(a, first, last, rand.Intn(last-first+1)+first) + quicksortHelper(a, first, pivotIndex-1) + quicksortHelper(a, pivotIndex+1, last) +} + +//O(1) +//Fungsi untuk melakukan sort menggunakan quicksort +func quicksort(a Interface) { + quicksortHelper(a, 0, a.Len()-1) +} + +type SliceOfInt []int +type SliceOfString []string + +func (a SliceOfInt) Len() int { return len(a) } +func (a SliceOfInt) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a SliceOfInt) Less(i, j int) bool { return a[i] < a[j] } +func (a SliceOfString) Len() int { return len(a) } +func (a SliceOfString) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a SliceOfString) Less(i, j int) bool { return a[i] < a[j] } + +func main() { + rand.Seed(time.Now().Unix()) + x := make(SliceOfInt, 10) + for i := 0; i < 10; i++ { + x[i] = rand.Intn(20) + } + fmt.Print("Before: ") + for i := 0; i < 10; i++ { + fmt.Print(x[i], " ") + } + fmt.Println() + quicksort(x) + fmt.Print("After: ") + for i := 0; i < 10; i++ { + fmt.Print(x[i], " ") + } + fmt.Println() + fmt.Println() + y := make(SliceOfString, 3) + + fmt.Print("Before: ") + y[0] = "Ruby" + y[1] = "Emerald" + y[2] = "Sapphire" + for i := 0; i < 3; i++ { + fmt.Print(y[i], " ") + } + + fmt.Println() + quicksort(y) + fmt.Print("After: ") + for i := 0; i < 3; i++ { + fmt.Print(y[i], " ") + } + fmt.Println() + +} diff --git a/README.md b/README.md index 1e1a43c..803c91d 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ ChangeLog: * 2014-09-22 added singly circular linked list and doubly circular linked list (Dikaimin) * 2014-09-22 added SliceDeque (Rizal) * 2014-10-02 added LinkBST (Dikaimin) +* 2014-12-11 added QuickSort, CombSort, Heapsort (Agung) TODO: ===== @@ -37,7 +38,7 @@ BOUNTY: * implement AVLTree +2500, RBTree +3000, SplayTree +2000, ArrayAVL, ArrayRB, ArraySplay +4000 * implement SliceHeap +900, BSTHeap +600 * implement Trie +3500, CompressedTrie +5500, BurstTrie +8000, HATTrie +12500 -* implement QuickSort +1500, HeapSort +500, Non-recursive Inplace MergeSort +1500, CombSort +800, etc, that allow Less interface +* implement Non-recursive Inplace MergeSort +1500, etc, that allow Less interface * implement BinarySearch, JumpSearch, InterpolationSearch +400 that Allow Less, Equal interface * implement R-Tree +5000, k-d Tree +8000 (using reflection) * implement any other data structure or algorithm (bounty may vary, contact me for details)