算法和数据结构中位数

一个中位数(median)是它所在集合的“中点元素”,当n为奇数时,i=(n+1)/2,当n为偶数是,中位数总是出现在1 (下中位数)和2(上中位数)。

找最大值/最小值问题,通过比较n-1次可以得出结果。

MINIMUM(A)  
min ← A[1]  
for i ← 2 to length[A]  
       do if min > A[i]  
       then min ← A[i]  
return min

 如果要同时找出最大值和最小值,则比较次数最少并不是2*n-2,而是3,我们可以将一对元素比较,然后把较大者于max比较,较小者与min比较,这样就只需要3

如果是一般的选择问题,即找出一段序列第i小的数,看起来要比找最大值或最小值要麻烦,其实两种问题的渐进时间都是4

RANDOMIZED-SELECT(A, p, r, i)
  if p = r
      then return A[p]
  q ← RANDOMIZED-PARTITION(A, p, r)
  k ← q - p + 1
  if i = k          ▹ the pivot value is the answer
      then return A[q]
  elseif i < k
      then return RANDOMIZED-SELECT(A, p, q - 1, i)
  else return RANDOMIZED-SELECT(A, q + 1, r, i - k)

 随机快排代码

RANDOMIZED-PARTITION(A,p,r)
{
i=RANDOM(p,r);
exchange(A[r],A[i]);
return PARTION(A,p,q);
}

 查找第i小的数字

#include <iostream>
 #include <cstdlib>
 using namespace std;
  
 int Partition(int *arr, int beg, int end)
 {
     int sentinel = arr[end];
     int i = beg-1;
     for(int j=beg; j<=end-1; ++j)
     {
         if(arr[j] <= sentinel)
         {
             i++;
             swap(arr[i], arr[j]);
         }
     }
     swap(arr[i+1], arr[end]);
  
     return i+1;
 }
  
 int RandomPartition(int *arr, int beg, int end)
 {
     int i = beg + rand() % (end-beg+1);
     swap(arr[i], arr[end]);
     return Partition(arr, beg, end);
 }
  
  
 int RandomSelect(int *a, int p, int r, int i)
 {
     if(p == r)
         return a[p];
     int q = Partition(a, p, r);
     int k = q-p+1;
     if(i == k)
         return a[q];
     else if(i < k)
         return RandomSelect(a, p, q-1, i);
     else
         return RandomSelect(a, q+1, r, i-k);
 }
  
 int main()  
 {  
     int a[] = {0, 89, 100, 21, 5, 2, 8, 33, 27, 63};  
     int num = 9;   
     int ith;
     cout << "序列为: ";
     for(int i=1; i<=num; ++i)  
         cout << a[i] << " ";
     cout << endl;
     ith = RandomSelect(a, 1, num, 2);
     cout << "序列中第2小的数字是: " << ith << endl;
     getchar();
  
     return 0;  
 }

 5

原文地址:https://www.cnblogs.com/tgkx1054/p/2607399.html