找到第 n 个最大数无限循环C++
Find nth largest number infinite loop C++
我有一个 N 个数字的向量,我想找到数组中的第 n 个数字。我正在使用快速排序的变体,但有时会遇到无限循环的问题,我认为这是如果最大的数字是两个数组中的唯一选项。一个数字可以在数组中出现很多次,所以,例如,如果我为 N 选择 10 并且我想找到第一个最大的数字,我可能会在左侧数组中以 {9,9} 结束,从而导致无限循环。我能做些什么来解决这个问题?这是我的代码。
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <vector>
using namespace std;
int partition(int n, int arrsize, vector<int> intarr); //pass vector by val
int main() {
int n, N;
cout << "Please enter n: " << endl;
cin >> n;
cout << "Please enter N: " << endl;
cin >> N;
vector<int> array;
srand(time(NULL));
for(i=0; i < N; i++) {
array.push_back(1 + rand() % N);
cout << array.at(i) << ", ";
}
//Get the nth largest value of array[N]
int arraylen = array.size();
cout << "nArraylen is " << arraylen << endl;
int result = partition(n, arraylen, array);
cout << "The " << n << "th largest number is: " << result <<endl;
return 0;
}
int partition(int n, int arrsize, vector<int> intarr) {
//1. Get a random value from the array:
int random = rand() % arrsize;
int pivot = intarr.at(random);
//2. Partition the array into 2 halves left < pivot > right
vector<int> left;
vector<int> right;
for(int j=0; j < arrsize; j++) {
if (intarr[j] >= pivot)
left.push_back(intarr[j]);
else if (intarr.at(j) < pivot)
right.push_back(intarr[j]);
else continue;
}
cout << "n n" << "Left = ";
for(int k = 0; k < left.size(); k++) {
cout << left.at(k) << ", ";
}
cout << endl << "Right = ";
for(int k = 0; k < right.size(); k++) {
cout << right.at(k) << ", ";
}
int leftlen = left.size();
int rightlen = right.size();
if (n < leftlen)
return partition(n, leftlen, left);
else if (n > (arrsize - rightlen)) {
n = n - (leftlen);
return partition(n, rightlen, right);
}
else return pivot;
}
由于您无论如何都要创建新向量(我想是因为您不想改变输入向量),因此您不妨避免将枢轴元素放在左侧或右侧。在这种情况下,如果枢轴原来是您要查找的元素,它将被 else return pivot
捕获,如果您最终得到分区都是相等元素的退化情况,则不会将任何内容放入左侧或右侧,并且分区的单个值将被正确返回。
此问题的方法是永远不要将枢轴元素放入正在排序的子向量中;因此,即使其中一个向量最终都是相同的元素,它最终仍然比原来短。这是快速排序的一个微妙之处,很少得到很好的解释,尽管 Sedgwick 确实讨论了提高快速排序在具有许多重复元素的向量上性能的方法。
检查任何一个
子数组是否为空将有助于检测无限循环,以及其他一些情况下的崩溃。
int leftlen = left.size();
int rightlen = right.size();
if (leftlen == 0 || rightlen == 0) /* break processing */
编辑 仅当其中一个数组为 0 并且另一个数组填充相同的值时,才有可能进行无限循环。
相关文章:
- 过载'operator new'如何导致无限循环?
- C++正则表达式无限循环
- 程序在尝试猜测它选择的随机数时进入无限循环?
- 遍历链表时的无限循环
- 循环链表:无限循环
- 比较两个字符串后卡在无限循环中
- 在做一段时间内检查字符的无限循环
- 逐字读取文本文件中的每一行并转换为 int(无限循环或崩溃?
- 在这个无限循环中,当输入 0 时终止,当输入 int 范围之外的任何内容时,程序行为不正常
- 可能的无限循环
- 超出 int 的值范围后的无限循环
- 为什么这段代码会导致无限循环?
- 运行无限循环的最小二叉树问题
- 在分配和发布递增循环迭代器时C++无限循环(gcc 错误?
- 连接线程时的无限循环
- 尝试在图形中查找最短路径时的无限循环
- 找到第 n 个最大数无限循环C++
- 矩阵遍历打印所有和最短路径 - 无限循环
- 在数组上使用时最大堆无限循环,但不用于向量
- 最小堆通过二叉树的数组表示;MoveDown函数无限循环