归并排序、快速排序
时间复杂度为o(nlogn)
分治思想:分治,顾名思义,就是分而治之(divide and conquer),将一个大问题分解成一个小的子问题来解决,小的问题解决了,大问题也就解决了。
(分治是一种解决问题的处理思想,递归是一种编程技巧,这两者并不冲突)
-
归并排序(Merge Sort)
核心思想:如果要排序一个数组,我们先把数组从中间分成前后两部分,然后对前后两部分分别排序,再将排好序的两部分合并在一起,这样整个数组就有序了。
写递归代码的技巧:
- 分析出递推公式
Merge_sort(p...r)=merge(merge_sort(p...q),merge_sort(q+1...p)) q=(q+r)/2
- 然后找到终止条件
p>=r 不用再继续分解
merge函数作用就是将已经有序的a[p...q]和a[q+1...r]合并成一个有序的数组。(我们申请一个临时数组temp,大小和a[]相同,用两个游标i,j,分别指向a[p...q]和a[q+1...r]的第一个元素,比较这两个元素a[i]和a[j],如果a[i]<a[j],我们就把a[i]放入到临时数组temp,并将i后移一位,否则将a[j]放入到数组temp,j后移一位。)
动态演示:
代码:(c)
void Merge(int a[], int temp[], int start, int mid, int end)
{
int i = start, j = mid + 1, k = start;
while (i != mid + 1 && j != end + 1)
{
if (a[i] <= a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
}
while (i != mid + 1)
temp[k++] = a[i++];
while (j != end + 1)
temp[k++] = a[j++];
for (i = start; i <= end; i++)
{
a[i] = temp[i];
}
}
//内部使用递归
void merge_sort(int a[], int temp[], int start, int end)
{
int mid;
if (start < end)
{
mid = start + (end-start) / 2; //避免溢出int
merge_sort(a, temp, start, mid);
merge_sort(a, temp, mid + 1, end);
Merge(a, temp, start, mid, end);
}
}
结论:
- 归并排序是一个稳定的排序算法。
- 归并排序的时间复杂度(最好、最坏、平均时间复杂度都是o(nlogn))。
- 归并排序不是原地排序算法,空间复杂度为o(n)。
-
快速排序(Quick_Sort)
核心思想:如果要排序的数组中下标从p到r之间的一组数据,我们选择p到r之间的任意一个数据作为pivot(分区点)。我们遍历p到r之间的数据,将小于pivot的放到左边,将大于pivot的放到右边,将pivot放到中间。经过这一步骤之后,数组p到r之间的数据就被分成了三部分,前面的p到q-1之间都是小于pivot的,中间是pivot,后面的q+1到r之间是大于pivot的。
- 递推公式:
quick_sort(p...r)=quick_sort(p...q-1)+quick_sort(q+1...r) q=pivot
- 终止条件:p>=r
动态演示:
代码:(c)
void swap(int* p1, int* p2)
{
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
int partition(int a[], int start, int end)
{
int pivot = a[start];
int i = end;
for (int j = end; j >start; j--)
{
if (a[j] > pivot)
{
swap(&a[i],&a[j]);
i++;
}
}
swap(&a[i],&a[start]);
return i;
}
void quick_sort(int a[],int start,int end)
{
if (start < end)
{
int q = partition(a,start,end); //获取分区点
quick_sort(a, start, q - 1);
quick_sort(a, q + 1, end);
}
}
结论:
- 快速排序是原地排序算法。
- 快速排序是一种不稳定的排序算法。
- 快速排序的时间复杂度(最好情况是o(nlogn),最坏情况是o(n²),平均情况是o(nlogn))