我正在尝试为包含double
值的向量实现MergeSort算法。我有以下代码。但是,在我的输入中,两个值被视为零并且不合适。有人能告诉我哪里出错了吗?
P.S:我是数据结构的新手,所以我不知道在这里正确使用iterator
。
代码:
#include <iostream>
#include <vector>
void sort(std::vector<double> vec);
std::vector<double> merge(std::vector<double> left, std::vector<double> right, int len);
std::vector<double> mergeSort(std::vector<double> vec, int len);
void sort(std::vector<double> vec) {
std::vector<double> tmp = mergeSort(vec, vec.size());
for (unsigned int i = 0; i < vec.size(); i++){
vec[i] = tmp[i];
std::cout << vec[i] << " ";
}
}
std::vector<double> merge(std::vector<double> left, std::vector<double> right, int len){
std::vector<double> ret(len + len);
int left_position = 0;
int right_position = 0;
int ret_position = 0;
while (left_position < len && right_position < len){
double left_value = left[left_position];
double right_value = right[right_position];
if (left_value < right_value){
ret.insert((ret.begin() + ret_position), left_value);
//ret[ret_position] = left_value;
ret_position++;
left_position++;
}
else {
ret.insert((ret.begin() + ret_position), right_value);
ret_position++;
right_position++;
}
}
while (left_position < len){
ret.insert((ret.begin() + ret_position), left[left_position]);
ret_position++;
left_position++;
}
while (right_position < len){
ret.insert((ret.begin() + ret_position), right[right_position]);
ret_position++;
right_position++;
}
return ret;
}
std::vector<double> mergeSort(std::vector<double> vec, int len){
if (len == 1){
return vec;
}
int middle = len / 2;
std::vector<double> left(middle);
std::vector<double> right(middle);
for (int i = 0; i < middle; i++){
left.insert((left.begin() + i), vec[i]);
}
for (int j = 0; j < middle; j++){
right.insert((right.begin() + j), vec[j + middle]);
}
left = mergeSort(left, middle);
right = mergeSort(right, middle);
std::vector<double> ret = merge(left, right, middle);
return ret;
}
int main(){
std::vector<double> vec;
vec.push_back(7.04);
vec.push_back(8.04);
vec.push_back(6.04);
vec.push_back(9.04);
vec.push_back(1.04);
vec.push_back(3.04);
vec.push_back(5.04);
vec.push_back(2.04);
vec.push_back(10.04);
vec.push_back(4.04);
vec.push_back(12.04);
vec.push_back(11.04);
sort(vec);
return 0;
}
输出为:1.04 2.04 4.04 5.04 0 7.04 8.04 0 9.04 0 12.04 0
这很奇怪。
(请注意,输入中的每个第三元素都被视为0)
答案 0 :(得分:1)
我已更正您的代码。
第一个问题是,正如 UmNyobe 所说的那样,在计算时会失去元素
int middle = len / 2;
使用构造函数时
std::vector<int>(size_type n);
构造一个包含n个元素0.0
的vecror
关于vector的构造函数的更多信息请阅读here。
使用时
vec.insert(iterator pos, const value_type& val);
你在位置pos之前插入一个新元素,并且增加向量的大小为1 在合并排序中,我建议您创建一个包含一些元素的向量,然后将它们分配给适当的值 例如,您可以在下面的代码中看到:
std::vector<double> ret(left.size() + right.size(), -1); // construct vector with left.size() + right.size() elements assigned to -1
int left_position = 0;
int right_position = 0;
int ret_position = 0;
while (left_position < left.size() && right_position < right.size()) {
double left_value = left[left_position];
double right_value = right[right_position];
if (left_value < right_value) {
ret[ret_position++] = left_value;
left_position++;
} else {
ret[ret_position++] = right_value;
right_position++;
}
}
更正后的代码:
#include <iostream>
#include <vector>
std::vector<double> merge(std::vector<double> left, std::vector<double> right);
std::vector<double> mergeSort(std::vector<double> vec);
void sort(std::vector<double>& vec) { // using reference here std::vector<double>& - to be able to change vector inside function
vec = mergeSort(vec);
for (unsigned int i = 0; i < vec.size(); i++){
std::cout << vec[i] << " ";
}
}
std::vector<double> merge(std::vector<double> left, std::vector<double> right) {
std::vector<double> ret(left.size() + right.size(), -1); // construct vector with left.size() + right.size() elements assigned to -1
int left_position = 0;
int right_position = 0;
int ret_position = 0;
while (left_position < left.size() && right_position < right.size()) {
double left_value = left[left_position];
double right_value = right[right_position];
if (left_value < right_value) {
ret[ret_position++] = left_value;
left_position++;
} else {
ret[ret_position++] = right_value;
right_position++;
}
}
while (left_position < left.size()) {
ret[ret_position++] = left[left_position++];
}
while (right_position < right.size()) {
ret[ret_position++] = right[right_position++];
}
return ret;
}
std::vector<double> mergeSort(std::vector<double> vec){
if (vec.size() < 2){
return vec;
}
int middle = vec.size() / 2;
std::vector<double> left(vec.begin(), vec.begin() + middle);
std::vector<double> right(vec.begin() + middle, vec.end());
left = mergeSort(left);
right = mergeSort(right);
std::vector<double> ret = merge(left, right);
return ret;
}
int main(){
std::vector<double> vec;
vec.push_back(7.04);
vec.push_back(8.04);
vec.push_back(6.04);
vec.push_back(9.04);
vec.push_back(1.04);
vec.push_back(3.04);
vec.push_back(5.04);
vec.push_back(2.04);
vec.push_back(10.04);
vec.push_back(4.04);
vec.push_back(12.04);
vec.push_back(11.04);
sort(vec);
return 0;
}
现在输出
1.04 2.04 3.04 4.04 5.04 6.04 7.04 8.04 9.04 10.04 11.04 12.04
您应该仔细阅读 vector 类的方法 这是一个关于c ++的好网站:http://www.cplusplus.com/reference/vector/vector/
答案 1 :(得分:0)
将原始集分成left
和right
子集时,您忘记了元素。
int middle = len / 2;
for (int i = 0; i < middle; i++){
...
}
for (int j = 0; j < middle; j++){
...
}
如果len
很奇怪,您将获得2*middle = len -1
。您可以更改为
for (int j = 0; j < len - middle; j++){
...
}
修改强> 您的整个程序基于左侧和右侧长度相等的事实。这意味着只有当输入向量的长度是2的幂时它才是正确的。 你需要重新考虑你的函数,假设左右大小不同 强>
处理向量时,你真的需要传递一个长度参数吗?例如
std::vector<double> ret(len + len);
合并功能中的可以是
std::vector<double> ret(left.size() + right.size());