Go版本:
// 快排(分治)
func QuickSort(arr []int, left, right int) {
var QuickSorting = func(arr []int, left, right int) int {
tmp := arr[right] // 1、从右向左依次选基准值tmp
for left < right {
for arr[left] <= tmp && left < right { // 2、每轮循环中先从左向右,遇到比基准值小的数则left++
left++
}
if left < right {
arr[right] = arr[left] // 3、直至遇到比基准值大的数x=array[left]为止,然后再交换基准值与较大值x的位置(保证基准值左侧的值都比基准值tmp小)
}
for arr[right] >= tmp && left < right { // 4、每轮循环中再从右向左,遇到比基准值大的数则right--
right--
}
if left < right { // 5、直至遇到比基准值小的数y=array[right]为止,然后再交换基准值与较小值y的位置(保证基准值右侧的值都比基准值tmp大)
arr[left] = arr[right]
}
}
arr[left] = tmp
return left
}
if left < right {
mid := QuickSorting(arr, left, right)
QuickSort(arr, left, mid-1)
QuickSort(arr, mid+1, right)
}
}
// 快排(非递归)// todo:待补充
// https://www.bilibili.com/video/av758822583/?vd_source=2c268e25ffa1022b703ae0349e3659e4
func QuickSortNotByRecursion(arr []int) {
}
// 堆排(大顶堆:每个节点的值都大于或等于其左右孩子节点的值)
func HeapSort(arr []int) {
var CreateHeap = func(arr []int, i, length int) {
tmp := arr[i]
// 注意for循环条件:是 j arr[j] { // 左右孩子节点中选较大的节点值,并与父节点比较大小
break // 若父节点值满足"大于或等于其左右孩子节点的值"则break,否则与较大的孩子节点相互交换
}
arr[i] = arr[j]
i = j
}
arr[i] = tmp // 将最终比较后较小值放到合适的位置
}
// 首次构建堆
l := len(arr)
for i := l / 2; i >= 0; i-- { // 从二叉树最后一个父节点从底向上遍历(最上面的父节点:i = 0;最后一个父节点下标:i = len(arr) / 2)
CreateHeap(arr, i, l)
}
// 再次重建堆
for i := l - 1; i > 0; i-- { // 从下往上不断在每轮循环中置换出当前最大值,arr长度i也逐渐减到0
arr[0], arr[i] = arr[i], arr[0] // swap 把大顶堆根节点(下标为0)上的最大值交换到末尾,置换出来.
CreateHeap(arr, 0, i)
}
}
// 归并
func MergeSort(arr []int, length int) {
var MergeSorting = func(arr1, arr2 []int, length1, length2 int) {
i, j := 0, 0
tempArr := make([]int, 0 /*, length1+length2*/)
// 1.分别将两个子数组中较小一方的值按大小顺序移动到临时数组tempArr中
for i < length1 && j < length2 {
if arr1[i] < arr2[j] {
tempArr = append(tempArr, arr1[i]) // 将较小值加入临时数组tempArr
i++
// fmt.Println("i ", i)
} else {
tempArr = append(tempArr, arr2[j])
j++
// fmt.Println("j ", j)
}
}
// 2.肯定存在一个子数组先移动完,所以需要将另一个未移动完的有序子数组剩下的元素继续移动到tempArr中
if i < length1 {
tmpArr = append(tmpArr, arr1[i:]...)
}
if j < length2 {
tmpArr = append(tmpArr, arr2[j:]...)
}
// 3.将合并数组值赋给原始数组
copy(arr, tmpArr) // arr = tempArr // 此赋值方式不会影响main()中原数组arr中的值,仅仅在该函数作用域内的结果是排好序的
// for i := 0; i < length1+length2; i++ {
// arr[i] = tmpArr[i]
// }
}
// 注意:下面的l1和l2不能写成 "len(arr)/2" 和 "len(arr)-l1"
if length > 1 { // 最后拆至每个子数组只有一个元素
l1 := length / 2
l2 := length - l1
arr1, arr2 := arr, arr[l1:] // arr1原数组前半部分、arr2原数组后半部分
MergeSort(arr1, l1) // 不断拆分数组长度直至长度为1
MergeSort(arr2, l2) // 不断拆分数组长度直至长度为1
MergeSorting(arr1, arr2, l1, l2)
// mid := length / 2
// arr1, arr2 := arr[:mid], arr[mid:] // arr1原数组前半部分、arr2原数组后半部分
// MergeSort(arr1, len(arr1)) // 不断拆分数组长度直至长度为1
// MergeSort(arr2, len(arr2)) // 不断拆分数组长度直至长度为1
// MergeSorting(arr1, arr2, len(arr1), len(arr2))
}
}
// 冒泡
func MaoPaoSort(arr []int) {
for i := 0; i < len(arr); i++ {
for j := i + 1; j < len(arr); j++ {
if arr[i] > arr[j] {
arr[i], arr[j] = arr[j], arr[i] // swap
}
}
}
}
func main() {
array := []int{5, 28, 73, 19, 6, 0, 5}
// MaoPaoSort(array)
// QuickSort(array, 0, len(array)-1)
// QuickSortNotByRecursion(array)
// HeapSort(array)
MergeSort(array, len(array))
fmt.Println(array)
return
}
C++版本:
/*******************************归并*******************************/
void merge_sort(int* array1, int len1, int* array2, int len2)
{
int i = 0;
int j = 0;
int k = 0;
//int tmp[10]; // 临时数组 后续要优化,不能固定为10
int* tmp = new int[10];
// 1.分别将两个子数组中较小一方的值按大小顺序移动到临时数组tmp中
while (i < len1 && j < len2)
{
if (array1[i] < array2[j])
{
tmp[k++] = array1[i++];
}
else
{
tmp[k++] = array2[j++];
}
}
// 2.肯定存在一个子数组先移动完,所以需要将另一个未移动完的有序子数组剩下的元素继续移动到tmp中
while (i < len1)
{
tmp[k++] = array1[i++];
}
while (j < len2)
{
tmp[k++] = array2[j++];
}
// 3.将合并数组值赋给原始数组
for (int q = 0; q < len1 + len2; q++)
{
array1[q] = tmp[q]; // int* subArray1 = array; subArray1中包含原数组的所有元素
}
free(tmp);
}
// 拆分函数
void merge(int* array, int len)
{
if (len > 1) // 最后拆至每个子数组只有一个元素
{
int len1 = len / 2;
int len2 = len - len1;
int* subArray1 = array;
int* subArray2 = array + len1;
merge(subArray1, len1);
merge(subArray2, len2);
merge_sort(subArray1, len1, subArray2, len2);
}
}
int main()
{
int test_array[7] = { 5, 28, 73, 19, 6, 0, 5 };
int len = sizeof(test_array) / sizeof(int);
int right = len - 1; // 下标从0开始
//maopao_sort(test_array, len);
//quick_sort(test_array, 0, right); // ok
//quick_sroting_not_by_recursion(test_array, 0, right); // ok
//heap_sort(test_array, len);
merge(test_array, len);