Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
|
|
@ -0,0 +1,93 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
list := []int{31, 41, 59, 26, 53, 58, 97, 93, 23, 84}
|
||||
fmt.Println("unsorted:", list)
|
||||
|
||||
quicksort(list)
|
||||
fmt.Println("sorted! ", list)
|
||||
}
|
||||
|
||||
func quicksort(a []int) {
|
||||
var pex func(int, int)
|
||||
pex = func(lower, upper int) {
|
||||
for {
|
||||
switch upper - lower {
|
||||
case -1, 0: // 0 or 1 item in segment. nothing to do here!
|
||||
return
|
||||
case 1: // 2 items in segment
|
||||
// < operator respects strict weak order
|
||||
if a[upper] < a[lower] {
|
||||
// a quick exchange and we're done.
|
||||
a[upper], a[lower] = a[lower], a[upper]
|
||||
}
|
||||
return
|
||||
// Hoare suggests optimized sort-3 or sort-4 algorithms here,
|
||||
// but does not provide an algorithm.
|
||||
}
|
||||
|
||||
// Hoare stresses picking a bound in a way to avoid worst case
|
||||
// behavior, but offers no suggestions other than picking a
|
||||
// random element. A function call to get a random number is
|
||||
// relatively expensive, so the method used here is to simply
|
||||
// choose the middle element. This at least avoids worst case
|
||||
// behavior for the obvious common case of an already sorted list.
|
||||
bx := (upper + lower) / 2
|
||||
b := a[bx] // b = Hoare's "bound" (aka "pivot")
|
||||
lp := lower // lp = Hoare's "lower pointer"
|
||||
up := upper // up = Hoare's "upper pointer"
|
||||
outer:
|
||||
for {
|
||||
// use < operator to respect strict weak order
|
||||
for lp < upper && !(b < a[lp]) {
|
||||
lp++
|
||||
}
|
||||
for {
|
||||
if lp > up {
|
||||
// "pointers crossed!"
|
||||
break outer
|
||||
}
|
||||
// < operator for strict weak order
|
||||
if a[up] < b {
|
||||
break // inner
|
||||
}
|
||||
up--
|
||||
}
|
||||
// exchange
|
||||
a[lp], a[up] = a[up], a[lp]
|
||||
lp++
|
||||
up--
|
||||
}
|
||||
// segment boundary is between up and lp, but lp-up might be
|
||||
// 1 or 2, so just call segment boundary between lp-1 and lp.
|
||||
if bx < lp {
|
||||
// bound was in lower segment
|
||||
if bx < lp-1 {
|
||||
// exchange bx with lp-1
|
||||
a[bx], a[lp-1] = a[lp-1], b
|
||||
}
|
||||
up = lp - 2
|
||||
} else {
|
||||
// bound was in upper segment
|
||||
if bx > lp {
|
||||
// exchange
|
||||
a[bx], a[lp] = a[lp], b
|
||||
}
|
||||
up = lp - 1
|
||||
lp++
|
||||
}
|
||||
// "postpone the larger of the two segments" = recurse on
|
||||
// the smaller segment, then iterate on the remaining one.
|
||||
if up-lower < upper-lp {
|
||||
pex(lower, up)
|
||||
lower = lp
|
||||
} else {
|
||||
pex(lp, upper)
|
||||
upper = up
|
||||
}
|
||||
}
|
||||
}
|
||||
pex(0, len(a)-1)
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
func partition(a sort.Interface, first int, last int, pivotIndex int) int {
|
||||
a.Swap(first, pivotIndex) // move it to beginning
|
||||
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) // swap into right place
|
||||
return right
|
||||
}
|
||||
|
||||
func quicksortHelper(a sort.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)
|
||||
}
|
||||
|
||||
func quicksort(a sort.Interface) {
|
||||
quicksortHelper(a, 0, a.Len()-1)
|
||||
}
|
||||
|
||||
func main() {
|
||||
a := []int{1, 3, 5, 7, 9, 8, 6, 4, 2}
|
||||
fmt.Printf("Unsorted: %v\n", a)
|
||||
quicksort(sort.IntSlice(a))
|
||||
fmt.Printf("Sorted: %v\n", a)
|
||||
b := []string{"Emil", "Peg", "Helen", "Juergen", "David", "Rick", "Barb", "Mike", "Tom"}
|
||||
fmt.Printf("Unsorted: %v\n", b)
|
||||
quicksort(sort.StringSlice(b))
|
||||
fmt.Printf("Sorted: %v\n", b)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue