0

下面是我编写的用于在 C++ 中查找未排序数组的最小元素的代码。

我应该如何编辑我的递归函数以找到数组中第二甚至第三小的元素?

我知道还有其他方法(我已经搜索过),但是我想知道如何使用像这样的递归函数来做到这一点,它只适用于最小数量。

int min(vector<int> &array, int &min, int &next_min, int left,int right)
{    
    int a;        
    int b;

    if(left == right) { 
        return array[left];
    } else {   
        int mid= (right+left)/2;

        a = min(array,left,mid);
        b = min(array,mid+1,right);

        if (a<b) 
            return b;
        else         
            return a;
    }
}

提前谢谢了

这是我寻找第二小的尝试:

#include<iostream>
#include<vector>
#include <cstdlib>

using namespace std;

int counter=0;

void minf(vector<int> &array,int left,int right,int &min, int &next_min);

int main()
{
    int next_min;

    cout << "Enter integers one line at a time. (Enter -999 to terminate)" << endl;

    vector<int> array;  // 
    int input;

    while(true){
        cin >> input;
        if(input == -999) //check for termination condition
        break;
        array.push_back(input);
    }

    int imin;
    int imax;

    cout<<"Enter imin, then imax"<<endl;
    cin>>imin;
    cin>>imax; 

    cout<<"Min number is " << next_min <<endl;

    cin.get();
    system("pause");
    return 0;
}

void minf(vector<int> &array,int left,int right,int &min, int &next_min)
{
    int a;
    int b;
    int c;
    int d;

    if(left == right) { 
        min = array[left];
        next_min = 2147483647;
    } else {
        int mid= (right+left)/2;

        minf(array,left,mid,a,b);
        minf(array,mid+1,right,c,d);

        if (a < b && a < c && a < d) {
            min = a;
            if (b<c && b <d)
                next_min = b;
            else if (c < b && c < d)
                next_min = c;
            else
                next_min = d;
        }    

        if (b < a && b < c && b < d){
            min = b;
            if (a<c && a <d)
                next_min = a;
            else if (c < b && c < d)
                next_min = c;
            else
                next_min = d;
        }

        if (c < a && c < b && c < d) {
            min = c;
            if (b<a && b<d)
                next_min = b;
            else if (a < b && a < d)
                next_min = a;
            else
                next_min = d;
        }   

        if (d < a && d < c && d < b){
            min = d;
            if (a<c && a <b)
                next_min = a;
            else if (c < b && c < a)
                next_min = c;
            else
                next_min = b;
        }     
    }
}
4

3 回答 3

1

即使您在每个步骤中将数组分成两半,您的搜索仍然是线性的(因为您的数据未排序)。给函数最后一个最小值怎么样?

int minf(vector<int> &array, int last_min)
{
    int minimum = 2147483647;
    for (vector<int>::iterator it = array.begin(); it != array.end(); ++it)
        if(*it < minimum && *it > last_min) minimum = *it;
    return minimum;
}

然后您可以编写一个打印 n 个最小元素的函数:

void printMins(vector<int> &array, int count)
{
    int last_min = -2147483648;
    while(count-- > 0)
    {
        last_min = minf(array, last_min);
        cout << last_min << endl;
    }
}
于 2013-05-04T16:30:23.107 回答
1

有什么理由不能使用std::sort(vector.beigin(), vector.end())吗?然后vector[0]是最小的,vector[1]是第二小的,依此类推......

于 2013-05-04T16:03:21.927 回答
1

这是一个n以递归方式查找最小元素的函数,希望对您有所帮助!

#include <vector>
#include <iostream>

using namespace std;

vector<int> nMin(const vector<int> &array, int n, int left, int right) {
    vector<int> result;
    if (left == right) {
        result.push_back(array[left]);
    } else {
        int mid = (right + left) / 2;
        vector<int> leftResult = nMin(array, n, left, mid);
        vector<int> rightResult = nMin(array, n, mid + 1, right);
        int i = 0;
        int l = 0;
        int r = 0;
        int L = leftResult.size();
        int R = rightResult.size();
        while (i < n && (l < L || r < R)) {
            i++;
            if (l < L) {
                if (r < R) {
                    if (leftResult[l] < rightResult[r]) {
                        result.push_back(leftResult[l++]);
                    } else {
                        result.push_back(rightResult[r++]);
                    }
                } else {
                    result.push_back(leftResult[l++]);
                }
            } else {
                result.push_back(rightResult[r++]);
            }
        }
    }
    return result;
}

int main() {
    vector<int> test = {-2, 6, 7, 1, 3, 7, 4, 2, 5, 0, 8, -2};
    vector<int> smallest3 = nMin(test, 3, 0, test.size() - 1);
    for (int num : smallest3) {
        cout << num << endl;
    }
}

n简要说明:从左右半边升序到最小的元素,调用它们leftResultrightResult,然后将两者合并,总是从两个部分结果中选择下一个最小的元素。这类似于归并排序,只是它只会返回n元素而不是对整个数组进行排序。

于 2013-05-04T16:23:57.387 回答