我正在尝试编写一个递归函数,通过选择对一个小数组进行排序。我可以加载和运行所有内容,但是数组{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);
}
}
答案 0 :(得分:1)
我无法清楚地看到如何调整您的策略以使您的功能正常运行。我认为你需要通过交换元素来对数组进行排序。要做到这一点,你需要:
valueArr
复制到tempArr
。tempArr
排序到位。这使valueArr
处于原始状态。我假设那是你的意图。在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);
}
进一步清理的建议。
sortFunc
。main
的返回类型更改为int
。这是一个清理过的版本。
#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_MAX或numeric_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
在valueArr
中找出最小值后,您需要确保不再访问相同的值,因此请跟踪其索引并更改其值
循环迭代从代码中的1+(counter)
开始,如果最小值在此之前呢?这就是你需要从头开始的原因。
我希望你明白我的观点。干杯!
答案 3 :(得分:0)
除了R Sahu的answer中提供的有用建议和提示外,以下函数模板还可用作选择的递归 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());