归并排序
void merge(int arr[], int tempArr[], int left, int mid, int right)//合并
{
//左半区第一个未排序
int l_pos = left;
//右半区第一个未排序
int r_pos = mid + 1;
//临时数组元素下标
int pos = left;
//合并
while (l_pos <= mid && r_pos <= right)
{
if (arr[l_pos] <= arr[r_pos]) //左半区第一个剩余元素更小
{
tempArr[pos++] = arr[l_pos++];
}
else
{
tempArr[pos++] = arr[r_pos++];
}
}
//合并左半区剩余
while (l_pos <= mid)
{
tempArr[pos++] = arr[l_pos++];
}
//合并右半区剩余
while (r_pos <= right)
{
tempArr[pos++] = arr[r_pos++];
}
//把临时数组合并后的元素复制回原来的数组
while (left <= right)
{
arr[left] = tempArr[left];
left++;
}
}
void msort(int arr[], int tempArr[], int left, int right) //归并排序
{
//只有一个元素不需要划分
if (left < right)
{
int mid = (left + right) / 2; //递归部分划分区域
msort(arr, tempArr, left, mid);
msort(arr, tempArr, mid + 1, right);
merge(arr, tempArr, left, mid, right);//合并排序区域
}
}
void merge_sort(int arr[], int n) //归并排序入口
{
int* tempArr = (int*)malloc(n * sizeof(int));
if (tempArr)
{
msort(arr, tempArr, 0, n - 1);
free(tempArr);
}
}
int main()
{
int arr[] = { 9,5,2,7,12,4,3,1,11 };
int n = 9;
for (auto x : arr)
{
std::cout << x << " ";
}
std::cout << std::endl;
merge_sort(arr, n);
for (auto x : arr)
{
std::cout << x << " ";
}
}
快速
#include<iostream>
int partition(int arr[], int low, int high)//快速排序
{
int pivot = arr[high];
int i = low;
for (int j = low; j < high; j++)
{
if (arr[j] < pivot)
{
std::swap(arr[j], arr[i++]);
}
}
std::swap(arr[i], arr[high]);
return i;
}
void qsort(int arr[], int low, int high) //递归划分
{
if (low < high)
{
int mid = partition(arr, low, high);
qsort(arr, low, mid - 1);
qsort(arr, mid + 1, high);
}
}
void quick_sort(int arr[], int len)//快速排序入口
{
qsort(arr, 0, len - 1);
}
int main()
{
int arr[] = { 9,5,2,7,12,4,3,1,11 };
int n = 9;
for (auto x : arr)
{
std::cout << x << " ";
}
std::cout << std::endl;
quick_sort(arr, n);
for (auto x : arr)
{
std::cout << x << " ";
}
}
堆排序
#include<iostream>
/*
arr 维护堆的数组
n 数组长度
i 维护堆的下标节点
//大顶堆
*/
void heapify(int arr[], int n, int i)
{
int largest = i; //假设父节点最大,下标i
int lson = i * 2 + 1;
int rson = i * 2 + 2;
//找出largest和他的两个子节点中谁最大,此时largest存最大的
if (lson < n && arr[largest] < arr[lson])
{
largest = lson;
}
if (rson < n && arr[largest] < arr[rson])
{
largest = rson;
}
if (largest != i) //假如存在比他大的子节点,重新交换largest和i.
{
std::swap(arr[largest], arr[i]); //i 和lagerst 交换了这两个都是下标,i存的是新的最大值的下标,largest是旧的要维护的节点的下标
heapify(arr, n, largest);//此时还要继续调整下面的堆结构
}
}
void heap_sort(int arr[], int n)//堆排序入口
{
//建堆 i是维护堆元素的第一个的下标 i=n-1 下标为i的父节点下标(i-1)/2 == n/2-1 相当于堆顶
int i;
for (i = n / 2 - 1; i >= 0; i--)
{
heapify(arr, n, i);
}
//排序 将堆顶和最后一个元素交换,最后一个元素离开,堆调整堆,每一个离开堆的元素相当于排好序了
// i=n-1 最后一个元素
for(i=n-1;i>0;i--)
{
std::swap(arr[i], arr[0]);
heapify(arr, i, 0); //本身元素有n个,交换完元素,被排除去堆外面,剩下n-1个就是i个,堆顶就是下标0,
}
}
int main()
{
int arr[] = { 9,5,2,7,12,4,3,1,11 };
int n = 9;
for (auto x : arr)
{
std::cout << x << " ";
}
std::cout << std::endl;
heap_sort(arr, n);
for (auto x : arr)
{
std::cout << x << " ";
}
}