GO作业:各种排序比较

我在自己电脑上跑了一下,用随机生成的数组,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)
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值