给你的脑子热热身:
Q1: 找到一个数组(互异)中的最大值
A1:
//伪代码
FindMax(arr)
max = arr[1]
for i=2 to arr.length()
if arr[i] > max
max = arr[i]
return max
可以看出上面过程需要通过 arr.length()-1 次比较
Q2: 找到一个数组(互异)中的最大值和最小值,最少需要经过几次比较?
A2:
是不是一下子就想到,2(arr.length()-1)*,也就是设min、max
恭喜你答错了!
真实情况是需要 3*floor(n/2) 次比较, 思路是,取一对输入的元素,先将他们进行比较,然后将大的跟max比,将小的跟min比,这样一来 每两个元素只要进行3次 比较。
好了,如果你不信是最小的话,你取3个元素先比较看看咯,3个元素的话,每3个元素需要5次比较,效率是0.6,而2个元素是0.6666……其实就是因为[n(n+1)/2] / n = (n+1)/ 2 是一个单调递增函数
回归正题
#include<iostream>
#include<stdlib.h>
using namespace std;
//你们所熟悉的快速排序,但是这里只用了一个指针
//也可以如第一篇博客所写的那样采用两个指针(头尾)
int Partition(int *arr, int left, int right)
{
int x = arr[right];
int i = left -1;
for (int j=left;j<right;j++)
{
if (arr[j]<=x)
{
i++;
int temp = arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
int temp = arr[i+1];
arr[i+1] = arr[right];
arr[right] = temp;
return i+1;
}
//
int Randomized_Partition(int *arr, int left, int right)
{
//随机获得一个(left,right)之间的索引,打乱arr的顺序,让算法的运行时间不随arr本身的排序有较大的波动
//并将这个索引的值作为 主元
int i = rand()%(right-left)+left;
int temp = arr[i];
arr[i] = arr[right];
arr[right] = temp;
return Partition(arr,left,right);
}
//选择的核心
//算法核心思想,采用快速排序的思想,找到一个“主元”
//使其前面(包括自身)元素的个数len== position
//需要注意的点:
//1、如果position<len,则arr[position]在 “主元”前面的数组
//2、反之在主元后面的数组
int Randomized_Select(int *arr, int left, int right, int position)
{
if (left==right)
return arr[right];
int q = Randomized_Partition(arr,left,right);
int len = q-left+1;
if (position==len)
return arr[q];
else if (position<len)
return Randomized_Select(arr,left,q-1,position);
else
return Randomized_Select(arr,q+1,right,position-len);
}
int main()
{
int midNum;
int data[10] = { 2,6,8,99,45,63,102,556,10,41 };
midNum = Randomized_Select(data, 0, sizeof(data)/sizeof(*data)-1,5);
cout << "midNum =" <<midNum;
return 0;
}
上述方法的期望运行时间(由于输入是随机,因此求得的是期望时间)
对于元素互异数组 A={p…q…r}
首先要知道: 第q个元素之前(包含自身)正好有k个元素的概率是 1/n
定义指示器随机变量Xk为
Xk = I {子数组[p…q]正好包含k个元素}
E[Xk] = 1/n
现在我们来求该方法运行时间的上界(小于等于这个界限)
1、k存在于[p,q-1]、[q+1,r]上,因为要求的是上界,因此假设数组A是最恶劣的单调递增。当q正好在k个元素时,可以得到
2、两边同时取期望得到
3、去除里面的max
4、使用替代法,同样因为求的是上界, 我们令E[T(n)]≤ cn,其中c是某个常数;O(n)≤ an,c是某个常数,上式继续转化为如下:
5、判断n的满足条件
=3= 推到过程打起来实在是太麻烦了!
有任何想法和见解十分欢迎私聊和评论,三人行必有我师!