我在自己电脑上跑了一下,用随机生成的数组,10000个元素,比较下来,冒泡和选择排序慢得非常稳定,真正可以用的还就是希尔排序和快速排序。
运行结果如下:
条目 | 次数 |
---|---|
冒泡排序调用及循环了: | 50,005,000次 |
选择排序调用及循环了: | 50,005,001次 |
插入排序调用及循环了: | 24,939,554次 |
又一种插入排序调用及循环了: | 24,954,590次 |
希尔排序调用及循环了: | 232,927次 |
我自己写的快速排序调用及循环了: | 194,813次 |
快速排序调用及循环了: | 252,328次 |
全部代码如下:
// 各种排序
package main
import (
"bufio"
"fmt"
"math/rand"
"os"
"strconv"
"strings"
"time"
)
// 定义初始数组切片变量
var arr []int
// 初始化,录入数组,并检验输入
func init() {
rand.Seed(time.Now().UnixNano())
for {
REINPUT:
fmt.Println("请输入一串整数数组,以空格隔开,以回车结束:")
var tmparr []int
reader, err := bufio.NewReader(os.Stdin).ReadString('\n')
if err != nil {
fmt.Println("您的系统输入有误!", err)
return
}
indata := strings.Split(strings.TrimSuffix(reader, "\n"), " ")
for i := 0; i < len(indata); i++ {
tmp, err := strconv.Atoi(indata[i])
if err != nil {
fmt.Println("您输入的有非数字或空格,请重试!\n", err)
goto REINPUT
}
tmparr = append(tmparr, tmp)
}
arr = tmparr
break
}
fmt.Println("未序数组为: ", arr)
}
// 冒泡排序
var dyb int
func sortBubble(a []int) []int {
dyb++
for j := len(a) - 1; j > 0; j-- {
for i := 0; i < j; i++ {
if a[i] > a[i+1] {
a[i], a[i+1] = a[i+1], a[i]
}
dyb++
}
dyb++
}
return a
}
// 选择排序
var dys int
func sortSelect(a []int) []int {
dys++
for i := 0; i < len(a); i++ {
min := i
for j := i + 1; j < len(a); j++ {
if a[j] < a[min] {
min = j
}
dys++
}
a[i], a[min] = a[min], a[i]
dys++
}
return a
}
// 插入排序,用了临时存放数据的一个变量
var dyi int
func sortInsert(a []int) []int {
dyi++
for i := 0; i < len(a); i++ {
p := i - 1
tmp := a[i]
for p >= 0 && a[p] > tmp {
a[p+1] = a[p]
p--
dyi++
}
a[p+1] = tmp
dyi++
}
return a
}
// 插入排序,没有用临时存放数据的变量
var dyii int
func sortIn(a []int) []int {
dyii++
for i := 1; i < len(a); i++ {
for j := i; j > 0; j-- {
if a[j] > a[j-1] {
dyii++
break
}
a[j], a[j-1] = a[j-1], a[j]
dyii++
}
dyii++
}
return a
}
// 希尔排序
var dyss int
func shellSort(arr []int) []int {
dyss++
length := len(arr)
gap := 1
if length/3 >= gap {
gap = length/3 + 1
}
for gap > 0 {
for i := gap; i < length; i++ {
tmp := arr[i]
j := i - gap
for j >= 0 && arr[j] > tmp {
arr[j+gap] = arr[j]
j -= gap
dyss++
}
arr[j+gap] = tmp
dyss++
}
gap = gap / 3
dyss++
}
return arr
}
// 快速排序,我自己改良后的代码
var dyf int
func sortFast(values []int, left, right int) []int {
dyf++
i, j := left, right
for i < j {
for values[j] >= values[left] && i < j {
j--
dyf++
}
for values[i] <= values[left] && i < j {
i++
dyf++
}
if i < j {
values[i], values[j] = values[j], values[i]
}
dyf++
}
if i > left {
values[i], values[left] = values[left], values[i]
}
switch {
case i-1 > left:
sortFast(values, left, i-1)
fallthrough
case right > i+1:
sortFast(values, i+1, right)
}
return values
}
// 快速排序,经典的算法
var dyq int
func quickSort(arr []int) []int {
dyq++
return _quickSort(arr, 0, len(arr)-1)
}
func _quickSort(arr []int, left, right int) []int {
dyq++
if left < right {
partitionIndex := partition(arr, left, right)
_quickSort(arr, left, partitionIndex-1)
_quickSort(arr, partitionIndex+1, right)
}
return arr
}
func partition(arr []int, left, right int) int {
dyq++
pivot := left
index := pivot + 1
for i := index; i <= right; i++ {
if arr[i] < arr[pivot] {
swap(arr, i, index)
index += 1
}
dyq++
}
swap(arr, pivot, index-1)
return index - 1
}
func swap(arr []int, i, j int) {
dyq++
arr[i], arr[j] = arr[j], arr[i]
}
//主程序
var arr1 []int
func main() {
for i := 0; i < 10000; i++ {
arr1 = append(arr1, rand.Intn(10000))
time.Sleep(time.Millisecond)
}
testSlices := make([][]int, 7)
for i := 0; i < len(testSlices); i++ {
testSlices[i] = make([]int, len(arr))
copy(testSlices[i], arr)
switch i {
case 0:
fmt.Println("排序后数组:", sortBubble(testSlices[i]))
fmt.Println("冒泡排序调用及循环了: ", dyb)
dyb = 0
case 1:
fmt.Println("排序后数组: ", sortSelect(testSlices[i]))
fmt.Println("选择排序调用及循环了: ", dys)
dys = 0
case 2:
fmt.Println("排序后数组: ", sortInsert(testSlices[i]))
fmt.Println("插入排序调用及循环了: ", dyi)
dyi = 0
case 3:
fmt.Println("排序后数组: ", sortIn(testSlices[i]))
fmt.Println("又一种插入排序调用及循环了: ", dyii)
dyii = 0
case 4:
fmt.Println("排序后数组: ", shellSort(testSlices[i]))
fmt.Println("希尔排序调用及循环了: ", dyss)
dyss = 0
case 5:
fmt.Println("排序后数组: ", sortFast(testSlices[i], 0, len(testSlices[i])-1))
fmt.Println("我的快速排序调用及循环了: ", dyf)
dyf = 0
case 6:
fmt.Println("排序后数组: ", quickSort(testSlices[i]))
fmt.Println("快速排序调用及循环了: ", dyq)
dyq = 0
}
}
fmt.Println("下面是随机生成的数组")
fmt.Println(arr1)
testSlices1 := make([][]int, 7)
for i := 0; i < len(testSlices1); i++ {
testSlices1[i] = make([]int, len(arr1))
copy(testSlices1[i], arr1)
switch i {
case 0:
fmt.Println("排序后数组:", sortBubble(testSlices1[i]))
fmt.Println("冒泡排序调用及循环了: ", dyb)
case 1:
fmt.Println("排序后数组: ", sortSelect(testSlices1[i]))
fmt.Println("选择排序调用及循环了: ", dys)
case 2:
fmt.Println("排序后数组: ", sortInsert(testSlices1[i]))
fmt.Println("插入排序调用及循环了: ", dyi)
case 3:
fmt.Println("排序后数组: ", sortIn(testSlices1[i]))
fmt.Println("又一种插入排序调用及循环了: ", dyii)
case 4:
fmt.Println("排序后数组: ", shellSort(testSlices1[i]))
fmt.Println("希尔排序调用及循环了: ", dyss)
case 5:
fmt.Println("排序后数组: ", sortFast(testSlices1[i], 0, len(testSlices1[i])-1))
fmt.Println("我的快速排序调用及循环了: ", dyf)
case 6:
fmt.Println("排序后数组: ", quickSort(testSlices1[i]))
fmt.Println("快速排序调用及循环了: ", dyq)
}
}
}