使用递归查找数组中的第k个最小元素?

时间:2015-10-17 21:12:20

标签: c++ arrays

#include <iostream>

using namespace std;

void moveToKthSmallest(int a[], int size, int k); 


int main() {

int theArray[17] = {42, 5, 412, 56, 14, 98, 488, 4882, 24, 4, 9, 67, 9424, 2, 1, 3, 5};
int num;

cout << "Move to the kth smallest number in the array (size of 17): " << endl;
cin >> num;
moveToKthSmallest(theArray, 17, num);


return 0;
}

void moveToKthSmallest(int a[], int size, int k) {
int pivot = size / 2;
int pivotValue = a[pivot];
int index1 = 0, index2 = 0;
int s1[size], s2[size]; //not sure about this


for (int i = 0; i < size; i++) {
    if (a[i] < pivotValue) {
        s1[index1] = a[i];
        index1++;
    }
    else {
        s2[index2] = a[i];
        index2++; 
    }
}

int s1Size = index1; //problem?
int s2Size = index2; //problem?

if (s1Size == k - 1) {
    cout << pivotValue;
}

else if (s1Size > (k - 1)) {
    moveToKthSmallest(s1, s1Size, k);
}

else if (s1Size < (k - 1)) {
    moveToKthSmallest(s2, s2Size, k - (s1Size - 1));
}
}

我要求用户输入一个数字(大于或等于0或小于或等于17),程序应输出已生成数组中的第k个最小数字。

以上是我的尝试,但每次运行它都会崩溃。我认为它与函数中的数组s1和s2的声明有关,可能与index1和index2生成的大小值有关。我尝试过使用向量和动态数组但是我在编译器中不断收到错误消息,例如&#34;错误:无法转换&#39; std :: vector **&#39;到&#39; int *&#39;争论&#39; 1&#39; to to&#39; void moveToKthSmallest&#34; ......说实话,我不太清楚这意味着什么。

我错过了一些明显的东西吗?

1 个答案:

答案 0 :(得分:-1)

第一个问题是这是标记的C ++而不是C.因此,您应该使用简单的int a[]而不是int sizestd::vector<int>

现在,在你的例子中,在你的例子中,每次递归时你都会遍历整个数组。

第二个问题,我不明白为什么在这里需要递归。通过对阵列进行一次迭代就可以找到答案。

最简单的方法是使用第二个数组,让我们说std::vector<int> smallest,然后迭代std::vector<int> a一次。

迭代每个元素时:

  • 如果smallest.size()已经k,且当前值大于smallest中的最后一个值,则继续a中的下一个值,否则删除smallest中的最后一个值。

  • 此时,smallest.size()始终小于k,因此将a中的当前值以保持smallest的方式添加到smallest {1}}数组按排序顺序。

在迭代结束时,smallest向量中的最后一个值是原始向量中的第k个最小值。

如果您想知道第k个最小值的位置,这只是对上述算法的一个小修改,通过跟踪smallest向量中的位置而不是值。

这似乎是一个更简单,更直接的解决方案,然后是一个复杂的基于递归的方法,具有令人困惑的旋转操作。此外,您的透视示例需要修改原始数组,而我的方法不需要修改,甚至可以与const std::vector<int>一起使用。

P.S。保持smallest按排序顺序并不是必需的。通过稍微修改算法,smallest可以保持未分类。这里的作业分配是将此算法调整为不要求smallest保持排序顺序。