快速排序:每次排序将数组分为以某元素为划分点, 大于该元素的值在该元素右边, 小于该元素的值在该元素左边, 以某元素为中心,分别对该元素左边和右边子数组进行快排.每次确定一个元素的位置, 则 使得多个元素有序, 所以称为快排。
堆排序: 将数组看成完全二叉树的形式, 根节点root与子节点node位置关系是2*root=node或者2*root+1=node, 构建大根堆小根堆( 堆顶记录大于(小于)或等于所有子节点记录 ), 根据性质,每次可将堆的最大值(最小值)找出来并放到指定位置, 再调整堆(除去以排好序的元素), 直到所有元素排好序为止。
归并排序: 利用分治法, 每次将数组一分为二, 生成子数组, 分别对子数组排序, 在对排好序的子数组进行合并, 直到生成 有序的完整数组为止。
三种排序实现。
void Pushdown(int *a, int low, int high)
{
int i = low, j = 2 * i;
int temp = a[i];
while (j <= high)
{
if (j<high&&a[j]>a[j + 1])
{
j++;
}
if (temp>a[j])
{
a[i] = a[j];
i = j;
j = 2 * i;
}
else break;
}
a[i] = temp;
}
//堆排序
void HeadSort(int *a, int n)
{
for (int i = n / 2;i >= 1;i--)
{
Pushdown(a, i, n);
}
for (int i = n;i >= 2;i--)
{
swap(a[1], a[i]);
Pushdown(a, 1, i - 1);
break;
}
}
//快速排序
void quicksort(int *a,int left, int right)
{
int i, j, temp, t;
if (left > right)
{
return;
}
i = left;
j = right;
temp = a[left];
while (i != j)
{
while (a[j] >= temp && i < j)
{
j--;
}
while (a[i] <= temp && i < j)
{
i++;
}
if (i < j)
{
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
a[left] = a[i];
a[i] = temp;
quicksort(a,left, i - 1);
quicksort(a,i + 1, right);
}
//合并排序
void merge(int* a, int l, int m, int h) {
if (l == h)
return;
int* b = (int*)malloc(sizeof(int) * (h - l + 1));
int i = l, j = m + 1;
int k = 0;
while (i <= m && j <= h)
b[k++] = a[i] > a[j] ? a[j++] : a[i++];
if (i <= m)
while (i <= m)
b[k++] = a[i++];
if (j <= h)
while (j <= h)
b[k++] = a[j++];
//回写
i = l;
k = 0;
for (; i <= h;)
a[i++] = b[k++];
}
void mergeSort(int* a, int l, int h) {
if (l >= h)
return;
int m = (h + l) / 2;
mergeSort(a, l, m);
mergeSort(a, m + 1, h);
merge(a, l, m, h);
}
快速排序递归爆栈加上这句:
//这句用于解决C++快速排序递归爆栈问题,加在头文件前面
#pragma comment(linker, "/STACK:1024000000,1024000000")
100000的数据快排已经炸了QWQ。