我曾尝试用Hoare的分区方案实现Quicksort算法,但是当我在测试列表void Quicksort::sort(std::vector<int> &list)
{
sort(list, 0, list.size() - 1);
}
void Quicksort::sort(std::vector<int> &list, int left, int right)
{
if (left - right <= 1) return; // no need to partition a single element
int pivot = left + (right - left) / 2; // <=> (left+right)/2, but avoids overflow
int endIndex = partition(list, pivot, left, right);
sort(list, 0, endIndex - 1);
sort(list, endIndex + 1, list.size() - 1);
}
int Quicksort::partition(std::vector<int> &list, int pivot, int left, int right)
{
while (true)
{
while (list[left] < list[pivot])
left++;
while (list[right] > list[pivot])
right--;
if (left != right)
std::swap(list[left], list[right]);
else
return left;
}
}
上运行它并打印出来时,我得到的数字是原始顺序。有人可以帮我发现我在做什么错吗?下面是我的实现。
{412, 123, 57, 12, 1, 5}
要调用列表std::vector<int> numbers = {412, 123, 57, 12, 1, 5};
Quicksort::sort(numbers);
for (int i = 0; i < numbers.size(); i++)
std::cout << numbers[i] << "\n";
上的Quicksort算法,请使用以下代码:
412
123
57
12
1
5
控制台输出为
if (left - right <= 1)
修改
修复了应为if (right - left <= 1)
的错误Segmentation fault: 11
之后,程序遇到错误{{1}}。这使我相信我正在尝试访问超出范围的内容。
答案 0 :(得分:4)
算法的分区部分未正确实现。特别是,left
可能会大于right
,并且
if (left != right)
std::swap(list[left], list[right]);
// ^^^^^^^^^^
可以超出范围访问向量。
查看以下代码段:
int partition(std::vector<int> &list, int left, int right)
{
// I'm calculating the pivot here, instead of passing it to the function
int pivot = list[left + (right - left) / 2];
while (true)
{
while (list[left] < pivot)
left++;
while (list[right] > pivot)
right--;
// Stop when the pivot is reached
if (left >= right)
return right;
// Otherwise move the elements to the correct side
std::swap(list[left], list[right]);
}
}
void sort(std::vector<int> &list, int left, int right)
{
// Execute only if there are enough elements
if (left < right)
{
int pivot = partition(list, left, right);
// As NiVer noticed, you have to limit the range to [left, right]
sort(list, left, pivot - 1);
sort(list, pivot + 1, right);
}
}
可测试的HERE。
还考虑使用迭代器以更通用的方式实现这些功能。
答案 1 :(得分:2)
我认为代码的问题(或至少一个问题)是以下几行:
.hasOwnProperty()
这始终考虑整个列表,而不仅考虑未排序的部分。您应该使用限制索引 {
"name": "admin@test.org",
"oldPassword": "1234",
"newPassword": "12345"
}
和sort(list, 0, endIndex - 1);
sort(list, endIndex + 1, list.size() - 1);
:
left