c++ - 合并排序数组 - 高效的解决方案

标签 c++ algorithm stl

这里的目标是将多个已经排序的数组合并成一个结果数组。

我写了下面的解决方案,想知道是否有办法改进这个解决方案

/*
    Goal is to merge all sorted arrays
*/
void mergeAll(const vector< vector<int> >& listOfIntegers,  vector<int>& result)
{

    int totalNumbers = listOfIntegers.size();
    vector<int> curpos;
    int currow = 0 , minElement , foundMinAt = 0;
    curpos.reserve(totalNumbers);

    // Set the current position that was travered to 0 in all the array elements
    for ( int i = 0; i < totalNumbers; ++i)
    {
        curpos.push_back(0);
    }

    for ( ; ; )
    {
        /*  Find the first minimum 
            Which is basically the first element in the array that hasn't been fully traversed
        */

        for ( currow = 0 ; currow < totalNumbers ; ++currow)
        {
            if ( curpos[currow] < listOfIntegers[currow].size() )
            {
                minElement = listOfIntegers[currow][curpos[currow] ];
                foundMinAt = currow;
                break;
            }
        }
        /* If all the elements were traversed in all the arrays, then no further work needs to be done */
        if ( !(currow < totalNumbers ) )
            break;
        /* 
            Traverse each of the array and find out the first available minimum value
        */
        for ( ;currow < totalNumbers; ++currow)
        {
            if ( listOfIntegers[currow][curpos[currow] ] < minElement )
            {
                minElement = listOfIntegers[currow][curpos[currow] ];
                foundMinAt = currow;
            }
        }
        /* 
            Store the minimum into the resultant array 
            and increment the element traversed
        */
        result.push_back(minElement);
        ++curpos[foundMinAt];
    }
}

对应的main是这样的

int main()
{
    vector< vector<int> > myInt;
    vector<int> result;

    myInt.push_back(vector<int>() );
    myInt.push_back(vector<int>() );
    myInt.push_back(vector<int>() );

    myInt[0].push_back(10);
    myInt[0].push_back(12);
    myInt[0].push_back(15);


    myInt[1].push_back(20);
    myInt[1].push_back(21);
    myInt[1].push_back(22);

    myInt[2].push_back(14);
    myInt[2].push_back(17);
    myInt[2].push_back(30);

    mergeAll(myInt,result);

    for ( int i = 0; i < result.size() ; ++i)
    {
        cout << result[i] << endl;
    }
}

最佳答案

您可以概括合并排序算法并使用多个指针。最初,它们都指向每个数组的开头。您在优先级队列中维护这些指针(按它们指向的值)排序。在每一步中,您在 O(log n) 中移除堆中的最小元素(n 是数组的数量)。然后输出提取的指针指向的元素。现在您将此指针递增到一个位置,如果您没有到达数组的末尾,则重新插入 O(log n) 中的优先级队列。以这种方式进行,直到堆不为空。如果总共有 m 个元素,则复杂度为 O(m log n)。元素以这种方式按排序顺序输出。

关于c++ - 合并排序数组 - 高效的解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3321913/

相关文章:

C++ STL 算法,如 'comm' 实用程序

c++ - 为什么 std::numeric_limits<long long>::max() 会失败?

c++ - 在 visual studio 6 中将安装程序作为 C++ 实用程序的一部分包含在内

c++ - 删除多个数组元素并移动数组的算法

c++ - 列表迭代器不可递增 - 运行时错误

arrays - 高效的数据结构,用于包含插入的非常长的字符数组

c++ - 在 C++ 中将连续范围映射到离散区间

c++ - exe中 Unresolved external symbol 错误,但dll中没有

c++ - binary_search、find_if 和 <functional>

c++ - 我必须从工厂返回一个指针吗?