【演算法】合併兩個排序的陣列
阿新 • • 發佈:2018-12-10
合併兩個排序的陣列
對於集合合併這類操作,其實不同的資料量,為了速度或者更小的空間有很多種做法,甚至可使用多執行緒併發處理都可以(下一節會實現該方式)。下面的例子基於單執行緒,且資料量較小的實現。
拉鍊法
對應合併集合我們可以選擇首先將集合1拷貝到集合3中,然後使用插入的方式將集合2插入到集合3中。 此方法的時間複雜度較高,有一種更優的方式實現該演算法,那就是拉鍊法。 以下則是演算法實現以及註釋: 演算法基於C++實現。
//以下方法又稱為拉鍊法
//1.2個迭代器指向2個容器的頭,啟動迴圈2個迭代器誰小將該值放入arr即可
//2.到最後肯定是一個容器遍歷完畢,將另一個容器的全部值放入arr即可
//預設arr1 arr2都有元素,arr為空
void merge(vector<int> arr1, vector<int> arr2, vector<int>& arr)
{
int i = 0, j = 0;
while (i < arr1.size() || i < arr2.size())
{
if (arr1[i] <= arr2[j])
{
arr.push_back(arr1[i]);
++i;
}
else
{
arr.push_back(arr2[j]);
++j;
}
}
//下面區域性變數可以由下面2個迭代器替換,copy提取除去,此處省略
//std::vector<int>::iterator iterBegin;
//std::vector<int>::iterator iterEnd;
if (i == arr1.size())
{
//arr1完畢 剩餘arr2的全部元素
auto iter2 = arr2.begin();
std ::advance(iter2, j);
//剩餘的arr2插入arr中
std::copy(iter2, arr2.end(), std::back_inserter(arr));
}
else if (j == arr2.size())
{
//arr2完畢 剩餘arr1的全部元素
auto iter1 = arr1.begin();
std::advance(iter1, j);
//剩餘的arr2插入arr中
std::copy(iter1, arr1.end(), std::back_inserter(arr));
}
}
時間複雜度為O(n1+n2)。 接下來我們可以嘗試多執行緒處理、以及其優化演算法、以及其進一步優化“跳躍表”方法。