1. 程式人生 > >找出N個無序數中第K大的數

找出N個無序數中第K大的數

大於 利用 while () define ray def tdi ++

使用類似快速排序,執行一次快速排序後,每次只選擇一部分繼續執行快速排序,直到找到第K個大元素為止,此時這個元素在數組位置後面的元素即所求

時間復雜度:

1、若隨機選取樞紐,線性期望時間O(N)

2、若選取數組的“中位數的中位數”作為樞紐,最壞情況下的時間復雜度O(N)

利用快速排序的思想,從數組S中隨機找出一個元素X,把數組分為兩部分Sa和Sb。Sa中的元素大於等於X,Sb中元素小於X。這時有兩種情況:

1. Sa中元素的個數小於k,則Sb中的第k-|Sa|個元素即為第k大數; 2. Sa中元素的個數大於等於k,則返回Sa中的第k大數。
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define    N 10

int Partition(int *array, int low, int high) {
    int temp = array[low];
    while (low != high) {
        while (low<high && array[high]>=temp) high--;
        array[low] = array[high];
        
while (low<high && array[low]<=temp) low++; array[high] = array[low]; } array[low] = temp; return low; } void findk(int k, int *array, int low, int high) { int pos; pos = Partition(array, low, high); if (pos == k - 1) printf("第%d大的數是%d\n", k, array[k - 1
]); else if (pos > k - 1) { //左邊堆元素個數Sa大於k,則在左邊堆中找第k大的數 findk(k, array, low, pos - 1); } else { //左邊堆元素個數Sa小於k,則在右邊堆中找第 k -Sa個元素 findk(k - pos, array, pos + 1, high); } } void printArray(int *a) { for (int i = 0;i < N;++i) { printf("%3d", a[i]); } printf("\n"); } int main() { int *a = (int*)calloc(N, sizeof(int)); srand(time(NULL)); for (int i = 0;i < N;++i) { a[i] = rand() % 100; } printArray(a); findk(5, a, 0, N - 1); return 0; }

找出N個無序數中第K大的數