C++ 为什么在合并排序中出现向量下标超出范围错误? 无效合并(向量dst、向量第一、向量第二) { int i=0,j=0; 而(i

C++ 为什么在合并排序中出现向量下标超出范围错误? 无效合并(向量dst、向量第一、向量第二) { int i=0,j=0; 而(i,c++,algorithm,sorting,mergesort,C++,Algorithm,Sorting,Mergesort,如果sz==2,&a[(sz/2)+1]将尝试获取a[2]的地址,这将导致此错误。如果sz==2,&a[(sz/2)+1]将尝试获取a[2]的地址,这将导致此错误。您的子向量指定不正确。 请记住,迭代器指定从开始到结束 因此,这将忽略向量中的中间元素和最后一个元素。 对于长度为2的短向量也是未定义的 void merge(vector<int> dst,vector<int> first,vector<int> second) { int i=0,j=

如果sz==2,
&a[(sz/2)+1]
将尝试获取a[2]的地址,这将导致此错误。

如果sz==2,
&a[(sz/2)+1]
将尝试获取a[2]的地址,这将导致此错误。

您的子向量指定不正确。
请记住,迭代器指定从开始到结束

因此,这将忽略向量中的中间元素和最后一个元素。
对于长度为2的短向量也是未定义的

void merge(vector<int> dst,vector<int> first,vector<int> second)
{
    int i=0,j=0;

    while(i<first.size()&&j<second.size())
    {
        if(first[i]<second[j])
        {
            dst.push_back(first[i]);
            i++;
        }
        else
        {
            dst.push_back(second[j]);
            j++;
        }
    }
    while(i<first.size()
    dst.push_back(first[i++]);

    while(j<second.size())
    dst.push_back(second[j++]);
}

void mergeSort(vector<int> &a)
{   
    size_t sz = a.size();
    cin.get();
    if(sz>1)
    {   
        vector<int> first(&a[0],&a[sz/2]);
        vector<int> second(&a[(sz/2)+1],&a[sz-1]);

        mergeSort(first);
        mergeSort(second);

        merge(a,first,second);  
    }
}

void MergeSort(int* a,size_t size)
{
   vector<int> s(&a[0],&a[size-1]);
   mergeSort(s);
}
或者试试更大的向量:{a,B,C,D,E,F,G,H,I}

    first:  {A,B}   0 -> 2 (where 2 is one past the end so index 0 and 1_
    second: {}      3 -> 3 (Since one past the end equals the start it is empty}
或者尝试更小的向量:{a,B}

    first:  {A, B, C, D}    0 -> 4 (4 is one past the end so index 0,1,2,3)
    second: {F, G, H}       5 -> 8 (8 is one past the end so index 5,6,7)
应该是:

    first:  {A}    0 -> 1
    second: {BANG} 2 -> 1

您的子向量指定不正确。
请记住,迭代器指定从开始到结束

因此,这将忽略向量中的中间元素和最后一个元素。
对于长度为2的短向量也是未定义的

void merge(vector<int> dst,vector<int> first,vector<int> second)
{
    int i=0,j=0;

    while(i<first.size()&&j<second.size())
    {
        if(first[i]<second[j])
        {
            dst.push_back(first[i]);
            i++;
        }
        else
        {
            dst.push_back(second[j]);
            j++;
        }
    }
    while(i<first.size()
    dst.push_back(first[i++]);

    while(j<second.size())
    dst.push_back(second[j++]);
}

void mergeSort(vector<int> &a)
{   
    size_t sz = a.size();
    cin.get();
    if(sz>1)
    {   
        vector<int> first(&a[0],&a[sz/2]);
        vector<int> second(&a[(sz/2)+1],&a[sz-1]);

        mergeSort(first);
        mergeSort(second);

        merge(a,first,second);  
    }
}

void MergeSort(int* a,size_t size)
{
   vector<int> s(&a[0],&a[size-1]);
   mergeSort(s);
}
或者试试更大的向量:{a,B,C,D,E,F,G,H,I}

    first:  {A,B}   0 -> 2 (where 2 is one past the end so index 0 and 1_
    second: {}      3 -> 3 (Since one past the end equals the start it is empty}
或者尝试更小的向量:{a,B}

    first:  {A, B, C, D}    0 -> 4 (4 is one past the end so index 0,1,2,3)
    second: {F, G, H}       5 -> 8 (8 is one past the end so index 5,6,7)
应该是:

    first:  {A}    0 -> 1
    second: {BANG} 2 -> 1

Martin是对的,问题是辅助向量的构造函数:

原始向量:1979272198

iter1:2,iter2:8

    mergeSort(first);
    mergeSort(second);

    // Must clear a before we start pushing stuff into.
    a.clear();   // Add this line.
    merge(a,first,second);  
向量v(iter1,iter2);//新向量:27219

谈到合并排序和其他排序算法,我发现了一个非常有用的web:


马丁是对的,问题是辅助向量的构造函数:

原始向量:1979272198

iter1:2,iter2:8

    mergeSort(first);
    mergeSort(second);

    // Must clear a before we start pushing stuff into.
    a.clear();   // Add this line.
    merge(a,first,second);  
向量v(iter1,iter2);//新向量:27219

谈到合并排序和其他排序算法,我发现了一个非常有用的web:


如何避免这种情况。一件事是使用特殊情况。但这不是一个好的代码。还有其他方法吗?@brett:编写
if(输入为空)是很常见的返回输入
。但请看Martin的答案。我如何避免这种情况。一件事是使用特殊情况。但这不是一个好的代码。还有其他方法吗?@brett:如果(输入为空),编写
是很常见的返回输入
。但是请看Martin的答案。为什么要在第一个和第二个数组中传递st+sz/2?为什么要使用]它可能会给出一个编译器错误?@brett:向量的构造函数需要两个迭代器。它们指向第一个元素,一个指向最后一个元素。因此,我们传递的向量“first”是一个past结束,因此应该等于第二个向量中的第一个元素。st+sz/2'。布雷特:遵循这些规则:这个
向量s(&a[0],&a[size-1]);
也是错误的。最后一个迭代器应该指向最后一个元素。
s(&a[0],&a[size])
非常感谢您的清晰解释。为什么要在第一个和第二个数组中传递st+sz/2?为什么要使用]这可能会导致编译器错误?@brett:向量的构造函数需要两个迭代器。它们指向第一个元素,一个指向最后一个元素。因此,我们传递的向量“first”是
st+sz/2'this是最后一个元素,因此应该等于第二个向量中的第一个元素。
st+sz/2'。布雷特:遵循这些规则:这个
向量s(&a[0],&a[size-1]);
也是错误的。最后一个迭代器应该指向最后一个元素的前面。
s(&a[0],&a[size])
非常感谢您的清晰解释。