话说,选择第N个最小值的问题,从前是有恐惧的.今天看了一下,<>关于这个方面的问题,受益匪浅.虽然,刚刚一个很简单的选择问题,我都写了一个小时,但只有自己在实现代码的时候,才知道是不是真的理解了.而且,这个东西不能凭记忆区一句一句写,那样写不出的.
思想就是,不断找出当前数组中一个确切的位置,可知当前位置之前有多少个元素小于等于该位置上的值,进而通过将该位置同目标位置进行比较.不断缩小范围,最终达到目的.
运行时间方面,是 θ(N). 分析过程很数学,我就不班门弄斧了.
贴吧,脑袋有点昏沉的感觉.
/*2011-05-02-19.20.c -- 期望线性时间选择*/
#include
#define SIZE (20)
int main (void) ;
int select (int * const array, const int left, const int right, const int ith) ;
int partition (int * const array, const int left, const int right) ;
void swap (int * const pLV, int * const pRV) ;
int main (void)
{
int array[SIZE] = {5, 6, 7, 9, 8, 4, 3, 2, 1, 10, 12, 11, 13, 14, 15, 16, 17, 19, 18, 20} ;
int size = SIZE ;
int ith = 19 ;
printf ("The %d %s least number is : %d/n", ith, ith > 3 ? "th" : (1 == ith ? "st" : (2 == ith ? "nd" : "rd")), select (array, 0, size - 1, ith)) ;
return 0 ;
}
int select (int * const array, const int left, const int right, const int ith)
{
int pivot, kth ;
if (left == right)
return array[left] ;
pivot = partition (array, left, right) ;
kth = pivot - left + 1 ;
if (ith == kth)
return array[pivot] ;
else if (ith < kth)
return select (array, left, pivot - 1, ith) ;
else
return select (array, pivot + 1, right, ith - kth) ;
}
int partition (int * const array, const int left, const int right)
{
int pivot, i, j ;
pivot = right ;
i = left ;
j = right - 1 ;
while (1)
{
while (i != right && array[i] < array[pivot])
i++ ;
while (j != left && array[j] >= array[pivot])
j-- ;
if (i < j)
swap (array + i, array + j) ;
else
break ;
}
swap (array + i, array + pivot) ;
return i ;
}
void swap (int * const pLV, int * const pRV)
{
int temp ;
temp = *pLV ;
*pLV = *pRV ;
*pRV = temp ;
}