go语言快速排序(优化内存)

(视频学习来自哔哩哔哩)
源代码:

package main

//交换的函数
func Swap(arr []int, i, j int){
	arr[i],arr[j]=arr[j],arr[i]
}
func QuickSort2(arr []int, left,right int){
	if (right-left)<1{//递归结束标志,当数组只有一个时认为时有序的,按说时right=left就可以,
	//但是考虑一种特殊情况,数组里只有两个数,[1,2],试着执行一下,low标志没有动,low=left,
	//然后递归调用左边,区间就变成了[left, left-1],这是right-left=-1.
		return
	}
	//以第一个作为基准(升序)
	posnum := arr[left]
	//定义区域
	low := left  //low需要++,最终使arr[left, low]都是小于基准
	high := right+1  //high-- 使arr[high, right]都是大于基准的
					 //可以将high := right,后面的代码相继就要改
	i := left+1   //i++使[low+1, i]都是等于基准的
	//开始移动,大的一后面,小的移前面,等的一中间
	for i<(high){//当i与 high+1重回结束循环
		if arr[i]>posnum{
			Swap(arr, i, high-1)
			high--
			
		}else if arr[i]<posnum{
			
			Swap(arr, i, low+1)
			i++
			low++
			//为什么>的时候不用i++呢:在小于的时候,交换过来的数已经做过了判断,
			// 已经是比基准小的数,而大于的时候, 交换的是后面的数,后面的数没有遍历到,
			//所以需要i不变,以便继续判断交换过来的数	
		}else{
			i++//等于则跳到下一个继续判断
		}
	}
	//不要忘了这一步,基准与low区间最后那个交换,要知道(left,low]都是比基准小的
	Swap(arr,left,low)
	//大小区域分别递归
	QuickSort2(arr, left, low-1)
	QuickSort2(arr, high, right)
	
}

单元测试:

import (
	"fmt"
	"time"
	"math/rand"
	"testing"
)

func TestQuickSort(t *testing.T){
	//创建数组
	arr := make([]int, 20,20)
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i:=0;i<20;i++{
		arr[i]=r.Intn(100)
	}
	fmt.Println("before sort",arr)
	QuickSort2(arr, 0, len(arr)-1)
	fmt.Println("after  sort",arr)


	
}

测试十组数据:

PS D:\goproject\src\go_code\排序总结> go test
before sort [75 80 88 65 25 42 60 72 69 71 31 36 62 91 56 56 63 91 4 29]
after  sort [4 25 29 31 36 42 56 56 60 62 63 65 69 71 72 75 80 88 91 91]
PASS
ok      go_code/排序总结        0.691s
PS D:\goproject\src\go_code\排序总结> go test
before sort [20 91 70 79 62 9 91 48 39 76 13 39 53 66 30 16 98 37 79 72]
after  sort [9 13 16 20 30 37 39 39 48 53 62 66 70 72 76 79 79 91 91 98]
PASS
ok      go_code/排序总结        0.422s
PS D:\goproject\src\go_code\排序总结> go test
before sort [57 28 77 57 88 35 35 13 38 53 15 47 67 36 73 70 65 83 90 45]
after  sort [13 15 28 35 35 36 38 45 47 53 57 57 65 67 70 73 77 83 88 90]
PASS
ok      go_code/排序总结        0.586s
PS D:\goproject\src\go_code\排序总结> go test
before sort [83 78 92 34 34 26 91 6 91 32 69 58 40 29 98 59 54 23 66 92]
after  sort [6 23 26 29 32 34 34 40 54 58 59 66 69 78 83 91 91 92 92 98]
PASS
ok      go_code/排序总结        0.418s
PS D:\goproject\src\go_code\排序总结> go test
before sort [44 49 23 70 21 33 46 11 88 31 92 94 81 20 32 0 20 38 56 16]
after  sort [0 11 16 20 20 21 23 31 32 33 38 44 46 49 56 70 81 88 92 94]
PASS
ok      go_code/排序总结        0.396s
PS D:\goproject\src\go_code\排序总结> go test
before sort [95 9 43 2 33 58 5 21 98 88 17 44 69 95 73 49 20 71 90 30]
after  sort [2 5 9 17 20 21 30 33 43 44 49 58 69 71 73 88 90 95 95 98]
PASS
ok      go_code/排序总结        0.419s
PS D:\goproject\src\go_code\排序总结> go test
before sort [9 55 88 95 2 42 53 47 66 55 9 42 35 40 87 14 51 52 54 3]
after  sort [2 3 9 9 14 35 40 42 42 47 51 52 53 54 55 55 66 87 88 95]
PASS
ok      go_code/排序总结        0.528s
PS D:\goproject\src\go_code\排序总结> go test
before sort [58 48 29 5 90 96 26 62 13 74 38 15 17 29 75 62 78 91 81 94]
after  sort [5 13 15 17 26 29 29 38 48 58 62 62 74 75 78 81 90 91 94 96]
PASS
ok      go_code/排序总结        0.409s
PS D:\goproject\src\go_code\排序总结> go test
before sort [80 73 25 48 21 80 24 80 40 52 61 34 26 94 13 26 89 38 14 19]
after  sort [13 14 19 21 24 25 26 26 34 38 40 48 52 61 73 80 80 80 89 94]
PASS
ok      go_code/排序总结        0.373s
PS D:\goproject\src\go_code\排序总结> go test
before sort [54 43 66 29 90 17 20 68 29 76 96 4 64 30 59 50 12 17 61 77]
after  sort [4 12 17 17 20 29 29 30 43 50 54 59 61 64 66 68 76 77 90 96]
PASS
ok      go_code/排序总结        0.688s
PS D:\goproject\src\go_code\排序总结> go test
before sort [41 20 31 16 42 89 99 11 75 26 49 36 8 35 91 85 20 59 47 66]
after  sort [8 11 16 20 20 26 31 35 36 41 42 47 49 59 66 75 85 89 91 99]
PASS
ok      go_code/排序总结        0.385s
PS D:\goproject\src\go_code\排序总结> go test
before sort [52 57 26 68 90 8 38 24 68 91 43 28 90 39 65 20 67 92 70 96]
after  sort [8 20 24 26 28 38 39 43 52 57 65 67 68 68 70 90 90 91 92 96]
PASS
ok      go_code/排序总结        0.424s
PS D:\goproject\src\go_code\排序总结> go test
before sort [62 82 58 69 15 80 87 71 68 85 5 1 25 0 53 91 32 40 56 34]
after  sort [0 1 5 15 25 32 34 40 53 56 58 62 68 69 71 80 82 85 87 91]
PASS
ok      go_code/排序总结        0.398s
PS D:\goproject\src\go_code\排序总结> go test
before sort [85 79 8 92 58 51 51 45 30 72 81 66 94 83 15 60 21 38 50 30]
after  sort [8 15 21 30 30 38 45 50 51 51 58 60 66 72 79 81 83 85 92 94]
PASS
ok      go_code/排序总结        0.411s

具体步骤在代码注释里面有,有点绕,我脑子比较笨,一早上才吃透
二分插入排序和快排可以组成一个完整的排序业务

大体 有大步:
1.因为用到递归, 首先写递归结束标志
2.确定基准,循环交换元素,交换标准:比基准小的放到[left,low]区间;比基准大的放到[high,right]区间;等于基准的在(low,high)区间
3.对[left,low],[high,right]区间重复第二步

优点:
速度快,比传统开辟内存的快排节约空间

猜你喜欢

转载自blog.csdn.net/qq_44477844/article/details/106568916