合并排序算法帮助
Merge Sort Algorithm Assistance
我正在尝试实现合并排序算法。我从算法书中提供的伪代码开始。伪代码将数组中的第一个位置指示为 1 而不是 0。我在尝试实现代码时遇到了非常困难。
这是我所拥有的。我尝试通过打印出每一步的结果来逐步执行递归,但此时它非常复杂。
#include <iostream>
#include <deque>
using size_type = std::deque<int>::size_type;
void print(std::deque<int> &v)
{
for(const auto &ref:v)
std::cout << ref << " ";
std::cout << std::endl;
}
void merge(std::deque<int> &vec, size_type p, size_type q, size_type r)
{
int n_1 = q - p;
int n_2 = r - q;
std::deque<int> left, right;
for(auto i = 0; i != n_1; i++)
left.push_back(vec[p + i]);
for(auto j = 0; j != n_2; j++)
right.push_back(vec[q + j]);
int i = 0, j = 0;
std::cout << "left = ";
print(left);
std::cout << "right = ";
print(right);
for(auto k = p; k != r; k++) {
if((i != n_1 && j != n_2) && left[i] <= right[j]) {
vec[k] = left[i];
i++;
}
else if(j != n_2){
vec[k] = right[j];
j++;
}
}
}
void merge_sort(std::deque<int> &A, size_type p, size_type r)
{
int q;
if(p < r - 1) {
q = (p + r)/2;
merge_sort(A, p, q);
merge_sort(A, q + 1, r);
merge(A, p, q, r);
}
}
int main()
{
std::deque<int> small_vec = {1, 6, 2, 10, 5, 2, 12, 6};
std::deque<int> samp_vec = {2, 9, 482, 72, 42, 3, 4, 9, 8, 73, 8, 0, 98, 72, 473, 72, 3, 4, 9, 7, 6, 5, 6953, 583};
print(small_vec);
merge_sort(small_vec, 0, small_vec.size());
print(small_vec);
return 0;
}
运行程序时,我得到以下输出:
left = 1
right = 6
left = 1 6
right = 2 10
left = 2
right = 12 6
left = 1 2 6 10
right = 5 2 12 6
1 2 5 2 6 10 12 6
错误在这里:(i != n_1 && j != n_2) && left[i] <= right[j])
当i != n_1
计算结果为假时vec[k] = right[j];
被执行 - 正确。
但是,如果i != n_1
计算结果为 true
,j != n_2
计算为错误,即 j = n_2
您的程序尝试再次执行此操作vec[k] = right[j];
即越过您的 deque 的边界。
重写 for 循环,如下所示: if (i<n_1 && (j>=n_2 || left[i] <= right[j])
这个循环只有在C++条件短路的情况下才起作用,即当j>=n_2
计算结果为true
时,left[i] <= right[j]
永远不会再次检查,并且您不会访问边界上的双端。
仅当i<n_1
为真且j>=n_2
为假时,才会检查left[i] <= right[j]
,否则将执行第二个分支。
在花费大量时间并在另一篇文章中获得一些有价值的帮助后,能够使算法正确运行。
正确的代码:
#include <iostream>
#include <deque>
using size_type = std::deque<int>::size_type;
void print(std::deque<int> &v)
{
for(const auto &ref:v)
std::cout << ref << " ";
std::cout << std::endl;
}
void print(int arr[], int size)
{
for(int i = 0; i != size; i++)
std::cout << arr[i] << " ";
std::cout << std::endl;
}
void merge(std::deque<int> &vec, size_type p, size_type q, size_type r)
{
int n_1 = q - p + 1;
int n_2 = r - q;
std::deque<int> left, right;
int i = 0, j = 0;
while(i < n_1)
left.push_back(vec[p + i++]);
while(j < n_2)
right.push_back(vec[j++ + q + 1]);
i = 0; j = 0;
//std::cout << "left = ";
//print(left);
//std::cout << "right = ";
//print(right);
for(auto k = p; k <= r; k++) {
if((i < n_1 && left[i] <= right[j]) || j >= n_2) {
vec[k] = left[i++];
}
else if(j < n_2){
vec[k] = right[j++];
}
}
}
void merge_sort(std::deque<int> &A, size_type p, size_type r)
{
int q;
if(p < r) {
q = (r + p) / 2;
std::cout << "q = " << q << std::endl;
//std::cout << "p = " << p << std::endl;
merge_sort(A, p, q);
merge_sort(A, q + 1, r);
merge(A, p, q, r);
}
}
int main()
{
std::deque<int> small_vec = {10, 3, 6, 4, 1, 5, 3, 9, 7, 2, 8};
std::deque<int> samp_vec = {2, 9, 482, 42, 3, 4, 9, 8, 73, 8, 0, 98, 72, 473, 72, 3, 4, 9, 7, 6, 5, 6953, 583};
print(samp_vec);
merge_sort(samp_vec, 0, samp_vec.size() - 1);
print(samp_vec);
return 0;
}
相关文章:
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 需要帮助设置在C++中使用的Potrace
- 基于ELO的团队匹配算法
- C++选择排序算法中的逻辑错误
- 在指针的帮助下,文本文件中单词的频率
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- 需要帮助为我的算法中的缺陷提供优雅的修复
- 合并排序算法编译错误 [帮助]
- 合并排序算法帮助
- 我需要一些关于这个C++算法的帮助
- 请比较两种常见的比较算法及其大O帮助
- 需要算法的帮助来找到DAG中的最大路径
- 需要帮助将 Kruskal 算法应用于使用 2D 结构存储数据的现有邻接矩阵程序
- A* *算法帮助c++
- 帮助我理解这个算法(简单)
- 由于指针指向父项,星形算法无法工作,请帮助修复它
- Tic-Tac-Toe C++算法调试帮助
- 关于反向运动学算法的帮助
- 需要帮助找出我在这个反转算法中做错了什么(基于合并排序)
- 需要帮助理解std::find算法