编程练习——求无序数组第K小的数
为同寝的家伙写了一个求一个无序数组中第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];
-
- }
public class Sort{ public int Partition(SortTag[] al,int start, int end){
SortTag p = al[start]; SortTag tmp; while(start<end){ while(start<end &&
al[end].compare(p)<=0) end–; tmp = al[start]; al[start] = al[end]; al[end] =
tmp; while(start<end && al[start].compare(p)>=0) start++; tmp = al[start];
al[start] = al[end]; al[end] = tmp; } return start; } public void
FindTopK(SortTag [] al,int k){ if(al.length < k){ return; } int mid = 0; int
low = 0; int high = al.length-1; while(low <= high){ mid =
Partition(al,low,high); if(mid < k){ low = mid+1; } else if(mid > k){ high =
mid-1; } else{ return ; } } } } class SortTag{ public Integer n; public Double
score; public SortTag(Integer n, Double score){ this.n = n; this.score =
score; } public int compare(Object o){ Double d = this.score -
((SortTag)o).score; if ( d > 0 + 1E-12) return 1; else if( d < 0-1E-12) return
-1; else return 0; } }
- }
注意这k个数可是无序的…如果想有序…再排序一下就可以了.