为同寝的家伙写了一个求一个无序数组中第k小数的程序。思想就是快排的思想。找一个点,然后放到末尾,然后将小于这个数的值放在数组前面,大于这个值的放在数组后面,然后在将这个末尾的数放回。这个末尾数放入的位置i代表已经找到第i小的数。下面你应该明白了吧,放入的位置如果是k,恭喜你找到了第k小的数。
同样找到第k大的数类似的解法,找到前k个最大数也一样。找一个数组的中位数也一样做。求n个数组的中位数也一样的做。求n个数组的前k个大数或小数也类似可以做。
这个程序的算法复杂度是O(n)
另外这个程序是交换了这个数组元素中的顺序的。现在考虑一下如果不交换过去数组中的元素顺序,并且不开辟一个O(n)空间。那么这个算法的平均复杂度是多少?考虑一下,写在评论中。谢谢。
- // swap two number
- void swap( int &i, int &j)
- {
- int temp = i;
- i = j;
- j = temp;
- }
- // find a position to partition the array
- int partition( int start, int end)
- {
- return end/2+start/2;
- }
- // quick sort
- int QuickSort( int a[], int start, int end)
- {
- if (start > end)
- {
- throw "error" ;
- }
- if (start == end)
- {
- return end;
- }
- int p = partition(start,end);
- int i =0;
- swap(a[p],a[end]);
- int j = end-1;
- while (j>=i)
- {
- while (a[i]<a[end])
- {
- i++;
- }
- while (j >= 0 && a[j]>a[end])
- {
- j--;
- }
- swap(a[i],a[j]);
- }
- swap(a[i],a[j]);
- swap(a[i],a[end]);
- return i;
- }
- // find the k-th smaller number
- int FindK( int a[], int num, int kth)
- {
- if (kth > num || kth <= 0)
- {
- throw "error: no such k-th number" ;
- }
- int k = kth-1; // because the array index starts with 0, not 1;
- int position= -1;
- int start = 0;
- int end = num-1;
- while (position != k)
- {
- position = QuickSort(a,start,end);
- if (position < k)
- {
- start = position+1;
- }
- else
- {
- end = position-1;
- }
- }
- return a[position];
- }
注意这k个数可是无序的..如果想有序..再排序一下就可以了.