在分配内存时合并排序逻辑失败。

时间:2016-06-02 21:17:11

标签: c++ sorting logic mergesort

我正在进行merge-sort的实现,它将根据长度对歌曲列表进行排序。我写了以下内容,并且无法理解我的逻辑中的缺陷。这些函数不返回已排序的列表,而是从原始列表的中间返回一个项目的列表。

vector<song> merge( vector<song> firstList, vector<song> secondList){
 vector<song> outPut;
 int i = 0; int n = 0;
 while( outPut.size() < (firstList.size() + secondList.size()-1 )){
    if( firstList[i].length < secondList[n].length){
        outPut.push_back( firstList[i]);
        i++;
    }else{
        outPut.push_back( secondList[n]);
        n++;
    }
 }
return outPut;
}
vector<song> mergeSortLength( vector<song> playlist){
 int scope = playlist.size()/2;
 vector<song> firstHalf( &playlist[0], &playlist[scope]);
 vector<song> secondHalf( &playlist[scope], &playlist[playlist.size()]);
 if ( firstHalf.size() != 1){
    firstHalf = mergeSortLength(firstHalf);
 }
 if ( secondHalf.size() != 1){
    secondHalf = mergeSortLength( secondHalf);
 }
 return merge( firstHalf, secondHalf);
}

如果我从

更改while循环条件
( outPut.size() < (firstList.size() + secondList.size() -1)){ 

( outPut.size() < (firstList.size() + secondList.size())){

虽然列表排序成功,但在编译器吐出之前它已经到了一半:

  

playList(27898,0x7fff78b7b000)malloc: * mach_vm_map(size = 7526769998340063232)失败(错误代码= 3)   * 错误:无法分配区域   ***在malloc_error_break中设置断点以进行调试   libc ++ abi.dylib:以std :: bad_alloc类型的未捕获异常终止:std :: bad_alloc   中止陷阱:6

我非常感谢任何人的帮助。从盯着它看,我的眼睛模糊不清。

2 个答案:

答案 0 :(得分:0)

我没有看到很多关注,但也许你想要

vector<song> secondHalf( &playlist[scope+1], &playlist[playlist.size()-1]);

&amp;播放列表[playlist.size()]没有-1我认为是你问题的根源, 但我没试过。

答案 1 :(得分:0)

在merge()中,代码不检查是否已到达向量的末尾,具体来说,如果i> = firstList.size()或n&gt; = secondList.size(),则在哪种情况下,其他向量的其余部分将被复制。 while语句的结尾不应该为-1。

VS抱怨使用&amp; playlist [playlist.size()]创建临时矢量,因为下标超出了范围。执行此操作的可选方法是使用begin()+ index,它是一个迭代器:

    vector<song> firstHalf( playlist.begin()+0, playlist.begin()+scope);
    vector<song> secondHalf( playlist.begin()+scope, 
                 playlist.begin()+playlist.size());

已经过了一天,因此发布固定版本以防任何人感兴趣。所有向量创建和回退都会增加很多开销,最好是进行一次分配,然后只使用迭代器或索引来处理子向量。

vector<song> merge( vector<song> firstList, vector<song> secondList){
    vector<song> outPut;
    size_t i = 0; size_t n = 0;
    while( outPut.size() < (firstList.size() + secondList.size()) ){
        if( firstList[i].length < secondList[n].length){
            outPut.push_back( firstList[i]);
            if(++i >= firstList.size()){
                do
                    outPut.push_back( secondList[n]);
                while(++n < secondList.size());
                break;
            }
        }else{
            outPut.push_back( secondList[n]);
            if(++n >= secondList.size()){
                do
                    outPut.push_back( firstList[i]);
                while(++i < firstList.size());
                break;
            }
        }
    }
    return outPut;
}

vector<song> mergeSortLength( vector<song> playlist){
    size_t scope = playlist.size()/2;
    vector<song> firstHalf( playlist.begin()+0, playlist.begin()+scope);
    vector<song> secondHalf( playlist.begin()+scope, playlist.begin()+playlist.size());
    if ( firstHalf.size() != 1){
        firstHalf = mergeSortLength(firstHalf);
    }
    if ( secondHalf.size() != 1){
        secondHalf = mergeSortLength( secondHalf);
    }
    return merge( firstHalf, secondHalf);
}