在上篇博客中寻找数组中的第k个数时每次排序所选择的pivot是随机选择的,在这篇博客中,我采用的是算法导论中讲的一种方法(算法导论上论证了该方法在最坏的情况下其运行时间都是线性的),尽可能使得划分后pivot两边数的个数差不多,具体步骤如下:
- 将数组中[low,high]之间的数以长度5为单位,分成1 + (high - low) / 5组("/"表示整数除)
- 寻找每一组中的中位数,先将每组进行选择排序(每组最多只有5个数),然后返回其中间的数
- 每一组返回的中位数又组成了一个新的数组,然后按上面的步骤进行递归处理,当新数组中只有一个元素时就得到了我们所需要的数pivot
- 使用pivot对数组划分为三部分[low,j-1],j,[j+1,high]
- 判断j是否是第k个元素,如是就返回,否则在[low,j-1]或是[j+1,high]中进行迭代
/*寻找数组中第i大的数*/
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void swap(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
/*选择排序,返回中间的元素*/
int SelectSort(int *arr, int low, int high)
{
int i, j;
int minIndex;
for (i = low; i < high; i++)
{
minIndex = i;
for (j = i + 1; j <= high; j+