C ++中的递归选择不能完全正常工作

时间:2017-02-10 06:40:15

标签: c++ arrays algorithm recursion selection-sort

我正在尝试编写一个递归函数,通过选择对一个小数组进行排序。我可以加载和运行所有内容,但是数组{3, 1, 8, 5}时的输出会一直输出为{1, 3, 3, 3}。我认为它与如何分配最小值有关,但我确切地想到了它的确切位置。有什么建议吗?

#include <iostream>
#include <conio.h>
#include <array>

using namespace std;

int arrLength = 4;
int minimum;
int counter = 0;

int sortedArr[];
int tempArr[];

void sortFunc(int, int);

int valueArr[4] = { 3,1,8,5 };
int tempArr[4] = {};

void main() {

    cout << "Before sorting..." << endl;

    for (int i = 0; i < 4; i++) {
        cout << valueArr[i] << " ";
    }

    cout << endl;

    sortFunc(4, counter);

    cout << "After sorting..." << endl;

    for (int i = 0; i < 4; i++) { //either broken here
        cout << tempArr[i] << " ";
    }

    _getch();
}

void sortFunc(int size, int counter) {
    minimum = valueArr[0];

    for (int i = 1 + (counter); i <  size; i++) { //or here
        if (valueArr[i] < minimum) {
            minimum = valueArr[i];
        }
    }

    tempArr[counter] = minimum;

    if (counter < size) {
        counter++;
        sortFunc(size, counter);
    }
}

4 个答案:

答案 0 :(得分:1)

我无法清楚地看到如何调整您的策略以使您的功能正常运行。我认为你需要通过交换元素来对数组进行排序。要做到这一点,你需要:

  1. 首先将valueArr复制到tempArr
  2. tempArr排序到位。这使valueArr处于原始状态。我假设那是你的意图。
  3. main中,使用:

    // Copy valueArr to tempArr
    std::copy(valueArr, valueArr+4, tempArr);
    

    sortFunc中,使用:

    void sortFunc(int size, int counter) {
       if ( size == counter )
       {
          return;
       }
    
        int minimum = tempArr[counter];
    
        for (int i = 1 + (counter); i <  size; i++) {
            if (tempArr[i] < minimum) {
                minimum = tempArr[i];
                std::swap(tempArr[counter], tempArr[i]); 
            }
        }
    
        sortFunc(size, counter+1);
    }
    

    进一步清理的建议。

    1. 不要使用任何全局变量。
    2. 将所有参数传递给sortFunc
    3. main的返回类型更改为int
    4. 这是一个清理过的版本。

      #include <iostream>
      #include <algorithm>
      
      using namespace std;
      
      void sortFunc(int arr[], int, int);
      
      int main() {
      
          cout << "Before sorting..." << endl;
      
          int valueArr[4] = { 3,1,8,5 };
          int tempArr[4] = {};
      
          for (int i = 0; i < 4; i++) {
              cout << valueArr[i] << " ";
          }
      
          cout << endl;
      
          // Copy valueArr to tempArr
          std::copy(valueArr, valueArr+4, tempArr);
          sortFunc(tempArr, 4, 0);
      
          cout << "After sorting..." << endl;
      
          for (int i = 0; i < 4; i++) { //either broken here
              cout << tempArr[i] << " ";
          }
          cout << endl;
      }
      
      void sortFunc(int arr[], int size, int counter) {
         if ( size == counter )
         {
            return;
         }
      
          int minimum = arr[counter];
      
          for (int i = 1 + (counter); i <  size; i++) {
              if (arr[i] < minimum) {
                  minimum = arr[i];
                  std::swap(arr[counter], arr[i]); 
              }
          }
      
          sortFunc(arr, size, counter+1);
      }
      

答案 1 :(得分:0)

我认为你不应该在行

初始化最小值

minimum = valueArr[0];

而是将其分配给大号或使用valueArr[counter + 1]

这种奇怪行为的原因可能是valueArr中的第一个条目实际上小于稍后在数组中遇到的条目,因此它将无法正确初始化...

ADD:请参阅INT_MAXnumeric_limits了解“大号”

ADD2:无论如何,仔细观察,你的递归有不正确的概念......如果你打算对数组进行排序,你必须总是将当前元素与你在每次迭代中选择的元素交换。否则你将开始失去元素,就像你一样。在任何情况下,递归可能不是解决排序的最佳方法......也许尝试两个嵌套循环

答案 2 :(得分:0)

您的代码中存在一些基本的逻辑错误,

void sortFunc(int size, int counter) {
    minimum = 2147483647; // Point 1
    int mytemp;
    for (int i = 0; i <  size; i++) { // Point 3
        if (valueArr[i] < minimum) {
            minimum = valueArr[i];  //Point 2
            mytemp = i;
        }
    }
    valueArr[mytemp] = 2147483647;
    tempArr[counter] = minimum;

    if (counter < size) {
        counter++;
        sortFunc(size, counter);
    }
}

1。 minimum变量应始终为最大可能值,您需要跟踪valueArr

中最小值的索引
  1. valueArr中找出最小值后,您需要确保不再访问相同的值,因此请跟踪其索引并更改其值

    < / LI>
  2. 循环迭代从代码中的1+(counter)开始,如果最小值在此之前呢?这就是你需要从头开始的原因。

  3. 我希望你明白我的观点。干杯!

答案 3 :(得分:0)

除了R Sahuanswer中提供的有用建议和提示外,以下函数模板还可用作选择的递归 STL类似实现排序算法:

#include <iterator>   // std::next
#include <algorithm>  // std::min_element

template<typename ForwardIt>
void sortFunc(ForwardIt first, ForwardIt last) {
    // base case
    if (first == last || std::next(first) == last)
        return; // empty range or range with a single element

    // recursive case
    auto selected_it = std::min_element(first, last);
    using std::swap;
    swap(*selected_it, *first);
    return selection_sort(++first, last);
}

这种方式可以对任何实现operator<的类型执行选择排序,并且它不仅限于int(如sortFunc()中所示)。

上面的实现允许tail recursion optimisation发生,因此,如果要对大型数组(或其他集合)进行排序,请不要忘记启用它。

您可以将上面的sortFunc函数模板与C样式数组一起使用(如示例所示):

// copy valueArr to tempArr
std::copy(valueArr, valueArr+4, tempArr);
// sort tempArr
sortFunc(tempArr, tempArr+4);

以及任何实现前向迭代器的STL容器:

std::vector<int> vec(valueArr, valueArr+4);
std::list<int> lst(valueArr, valueArr+4);
std::forward_list<int> fwdlst(valueArr, valueArr+4);

sortFunc(vec.begin(), vec.end());
sortFunc(lst.begin(), lst.end());
sortFunc(fwdlst.begin(), fwdlst.end());