合并排序:分段错误核心转储

Merge Sort: Segmentation error Core Dumped

本文关键字:核心 转储 错误 分段 排序 合并      更新时间:2023-10-16

我阅读了合并排序算法的理论,并在此基础上,我使用 STL Vector 类编写了合并C++排序的实现。

我知道互联网上关于合并排序的万亿篇文章中的任何一篇复制粘贴都可以解决这个问题,但我想自己尝试一下。

当我运行代码时,我得到分段错误核心转储错误,这是由递归函数未终止引起的。 任何人都可以帮我找到代码中的错误。

#include<iostream>
#include<vector>
void merge(std::vector<int>& arr,int last,int begin,int mid);
void mergeSort(std::vector<int>& arr,int begin, int last){ 
std::cout<<"In merge sort";
int mid; 
if(begin<last){
mid = (begin+last)/2;
mergeSort(arr,begin,mid);
mergeSort(arr,mid,last);
merge(arr,last,begin,mid);
} 
return;
}
void merge(std::vector<int>& arr ,int last,int begin,int mid){
if(last==begin){
std::cout<<"Returned form finger";
return; 
}
int b=begin,c=mid;
std::vector<int> temp;
while(b<mid&&c<last){
if(arr[b]<arr[c]){
temp.push_back(arr[b]);
b++;
}
else{
temp.push_back(arr[c]);
c++;
}
}
while(b<mid){temp.push_back(arr[b]);}
while(c<last){temp.push_back(arr[c]);}
arr.swap(temp);
return;
}

int main(){
std::vector<int> arr({2,4,1,5,3,6,2,4,3});   
for(auto it=arr.begin();it!=arr.end();++it){
std::cout<<*it<<' '; 
}
std::cout<<'n';
mergeSort(arr,0,8);
for(auto it=arr.begin();it!=arr.end();++it){
std::cout<<*it<<' '; 
}
return 0;
}

我使用 gcc 版本 9.3.0 使用终端命令编译代码

$ gcc filename.cpp -lstdc++

分析代码后,我认为问题出在合并函数中,但我无法指出它在哪里。如果有人可以帮助我,如果可能的话,建议一些优化我的代码的方法,那将是有帮助的。

所以你的递归是错误的。在main中,您有一个包含九个元素的向量。

std::vector<int> arr({2,4,1,5,3,6,2,4,3});

你这样称呼mergeSort

mergeSort(arr,0,8);

因此,要mergeSort的第三个参数是您要排序的向量的最后一个有效索引(最好使用arr.size() - 1(。换句话说,mergeSort是对包含范围(0,8(进行排序。

现在在merge_sort你有这个

void mergeSort(std::vector<int>& arr,int begin, int last) { 
...
mergeSort(arr,begin,mid);
mergeSort(arr,mid,last);
...
}

召回合并排序是对包含范围(开始、最后(进行排序。因此,您的递归将对两个包含范围(开始,中间(和(中,最后(进行排序。换句话说,mid被列入了两次。

由于(非常令人钦佩(您想自己编程,我将让您找出解决方法。

除了其他答案之外,您的merge函数还有一个严重的问题。用于将剩余元素复制到temp的代码如下所示:

while (b < mid) { temp.push_back(arr[b]); }
while (c < last) { temp.push_back(arr[c]); }

请注意,从不递增bc索引。这是一个无限循环,最终会耗尽内存调用push_back。简单的修复程序如下所示:

while (b < mid) { temp.push_back(arr[b++]); }
while (c < last) { temp.push_back(arr[c++]); }