使用向量在 c++ 中合并排序实现
Merge sort implementation in c++ using vectors
我正在尝试使用 C++ 中的向量实现合并排序,这是我正在执行的以下代码:
#include <iostream>
#include <vector>
using namespace std;
void merge(vector<int> &a, int l, int m, int r) {
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;
int L[n1], R[n2];
for (i = 0; i < n1; i++) {
L[i] = a[l + i];
}
for (j = 0; j < n2; j++) {
L[j] = a[m + 1 + j];
}
i = 0;
j = 0;
k = l; //merged array
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
a[k] = L[i];
i++;
} else {
a[k] = R[j];
j++;
}
k++;
}
while (i < n1) {
a[k] = L[i];
i++;
k++;
}
while (j < n2) {
a[k] = R[j];
j++;
k++;
}
}
void mergeSort(vector<int> &a, int l, int r) {
if (l < r) {
int m = l + (r - l) / 2;
mergeSort(a, l, m);
mergeSort(a, m + 1, r);
merge(a, l, m, r);
}
}
int main() {
int n;
std::cin >> n;
vector<int> a(n);
for (int i = 0; i < a.size(); i++) {
cin >> a[i];
}
mergeSort(a, 0, a.size() - 1);
for (int i = 0; i < a.size(); i++) {
cout << a[i];
}
}
当我执行此操作并输入任何值时,我得到数组中返回的垃圾值,a[i] = 7405024
,代码是否由于我无法就地更改向量的值而给我错误,还是还有其他东西。
问题出在merge
函数上
for(j=0;j<n2;j++)
{
R[j]=a[m+1+j]; // not L[j]
}
当您使用向量实现时,建议将L
和R
也更改为向量。默认情况下,C++不支持 VLA。一些编译器可能会接受,但应避免完全使用。
std::vector<int> L(n1);
std::vector<int> R(n2);
我可以看到的一个明显变化是
IN merge() function
for(j=0;j<n2;j++)
{
R[j]=a[m+1+j];
}
因为这些值必须存储在RIGHT
向量中。
问题是你初始化了R
。与其编写循环复制到L
和R
,不如直接初始化它们。
std::vector<int> L(a.begin() + l, a.begin() + m + 1);
std::vector<int> R(a.begin() + m + 1, a.begin() + r + 1);
请注意,在任何地方使用迭代器更容易。
using iter = std::vector<int>::iterator;
void merge(iter l, iter m, iter r) {
std::vector<int> L(l, m);
std::vector<int> R(m, r);
iter i = L.begin();
iter j = R.begin();
while (i != L.end() && j != R.end()) {
if (*i < *j) {
*l = *i;
i++;
} else {
*l = *j;
j++;
}
l++;
}
std::copy(i, L.end(), l);
}
void mergeSort(iter l, iter r) {
std::size_t d = std::distance(l, r);
if (d > 1) {
iter m = l + (d / 2);
mergeSort(l, m);
mergeSort(m, r);
merge(l, m, r);
}
}
int main() {
std::size_t n;
std::cin >> n;
std::vector<int> a(n);
for (int & i : a) {
std::cin >> i;
}
mergeSort(a.begin(), a.end());
for (int i : a) {
std::cout << i;
}
}
请注意,您可以l
前进,直到在初始化L
之前找到*m
后排序的元素,这样可以节省一些复制。
您可以使用以下代码实现合并排序:
vector<int> merge(vector<int> l,vector<int> r)
{
vector<int> res;
int i=0;
int j=0;
while(i!=l.size() && j!=r.size())
{
if(l[i]<=r[j])
{
re.push_back(l[i++]);
}
else
{
re.push_back(r[j++]);
}
}
while(i!=l.size())
re.push_back(l[i++]);
while(j!=r.size())
re.push_back(r[j++]);
return res;
}
vector<int> merge_d(vector<int>&A, int s,int e)
{
if(s-e==0)
{
vector<int> t;
t.push_back(A[s]);
return t;
}
int m=(s+e)/2;
vector<int> l;
vector<int> r;
l=merge_d(A,s,m);
r=merge_d(A,m+1,e);
return merge(l,r);
}
代码中的主要问题是你根本不初始化R
。初始化循环中有一个简单的错别字,可能是剪切和粘贴错误:L[j] = a[m + 1 + j];
应该是
R[j] = a[m + 1 + j];
另请注意,C++指定包含第一个元素的索引并排除最后一个元素的索引的切片是惯用的。此约定在 C、Python 和许多其他语言中使用,允许更简单、更通用的代码,您可以使用l == h
指定空切片。它也不太容易出错,因为不需要+1
/-1
调整,并且可以安全地使用无符号索引类型(例如size_t
(。
最后,int L[n1], R[n2];
是 C99 声明,它是对C++的扩展。即使在支持 VLA 的环境中,为它们分配自动存储也会导致足够大的集出现堆栈溢出。您应该对这些临时数组使用vector
。
这些向量可以直接从向量片初始化,从而避免容易出错的复制循环:
vector<int> L(a.begin() + l, a.begin() + m);
vector<int> R(a.begin() + m, a.begin() + r);
这是一个修改版本:
#include <iostream>
#include <vector>
using namespace std;
void merge(vector<int> &a, size_t l, size_t m, size_t r) {
vector<int> L(a.begin() + l, a.begin() + m);
vector<int> R(a.begin() + m, a.begin() + r);
size_t i = 0;
size_t j = 0;
size_t k = l; // index into the merged vector slice
size_t n1 = m - l;
size_t n2 = r - m;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
a[k++] = L[i++];
} else {
a[k++] = R[j++];
}
}
while (i < n1) {
a[k++] = L[i++];
}
// the last loop in redundant as the remaining elements from R are already at
// the end of a
}
void mergeSort(vector<int> &a, size_t l, size_t r) {
if (r - l >= 2) {
size_t m = l + (r - l) / 2;
mergeSort(a, l, m);
mergeSort(a, m, r);
merge(a, l, m, r);
}
}
int main() {
size_t n;
std::cin >> n;
vector<int> a(n);
for (size_t i = 0; i < a.size(); i++) {
cin >> a[i];
}
mergeSort(a, 0, a.size());
for (size_t i = 0; i < a.size(); i++) {
cout << a[i];
}
return 0;
}
相关文章:
- 使用C++程序合并排序没有得到正确的输出
- 用于合并排序的合并函数
- 合并排序不排序自创建数组类 c++
- 仅在大型阵列上出现合并排序分段错误
- C++合并排序可视化工具
- 没有输出的合并排序我做错了什么?
- 字符串上的合并排序上的 Seg 错误
- 使用向量在 c++ 中合并排序实现
- 我无法让我的合并排序实现运行
- 合并排序:分段错误核心转储
- 合并排序中的错误计数:计数反转
- C++ 多线程 - 与线程合并排序的算法替代
- C++中合并排序算法的奇怪行为
- 合并排序没有给我任何输出
- C++ 中的合并排序
- 数组为此合并排序函数提供了正确的输出,但向量给出了不正确的输出.出了什么问题?
- 在实现合并排序代码时无法计算所有反转
- 在C++中使用迭代器合并排序
- 运行合并排序递归算法时EXC_BAD_ACCESS错误
- 我的C++合并排序代码不起作用。我在这里错过了什么?