C++-無秩序配列指定範囲のtop kを求める

1840 ワード

例:6,1,8,2,9,5,7,2~5番目の小さなサブ配列を探し出す.
上の配列を並べ替えると1,2,5,6,7,8,9が得られ,そのうち2~5番目に小さい区間のすべての数が2,5,6,7であることが容易に分かる.
コード:
#include 
#include 

int flag = 0;

void Qselect(int arr[], int low, int high, int k1, int k2) {
    if (high <= low) return; //              
    int i = low;
    int j = high + 1;
    int key = arr[low]; //          
    while (true)
    {
        while (arr[++i] < key)
            if (i == high) break;
        while (arr[--j] > key)
            if (j == low) break;
        if (i >= j) break; //                
        int temp = arr[i]; //    i   j       
        arr[i] = arr[j];
        arr[j] = temp;
    }
    int temp = arr[low];  //    low   j       
    arr[low] = arr[j];
    arr[j] = temp;
    if (j > k1) //         k1
    {
        if (j == k2) //         k2          
            flag = 1;
        Qselect(arr, low, j - 1, k1, k2); //   low ~ j - 1               (    )
    }
    else if (j < k1)
        Qselect(arr, j + 1, high, k1, k2); //   low ~ j - 1                 
    else return; //           k1          
}

int main()
{

    int arr[1001], n, k1, k2;
    std::cout << "         :";
    std::cin >> n;
    std::cout << "         :";
    for (int i = 0; i < n; i++)
        std::cin >> arr[i];
    std::cout << "       :";
    std::cin >> k1 >> k2;
    Qselect(arr, 0, n, k1, k2);
    if (flag) { //        k2            
        for (int i = k1; i <= k2; i++)
            std::cout << arr[i] << " ";
    }
    else { //        k1   n             
        Qselect(arr, k1, n, k2, k1);
        for (int i = k1; i <= k2; i++)
            std::cout << arr[i] << " ";
    }
    return 0;
}