数组——两个有序数组的合并
題目:有元素按照遞增有序排列的兩個數組arr,和brr,將brr的元素合并到arr中,且arr中的元素依然有序。arr的大小足夠存放arr的有效元素和brr的有效元素。
例如:
arr[10] = {1,2,3};m=3//m為arr的有效數據個數
brr[7] = {1,2,3,4,5,6,7};n = 3//n為brr的數組長度(元素都有效)
合并后:arr[10] = {1,1,2,2,3,3,4,5,6,7};
主要講述三種方法:
1.空間換時間(O(n),S(n))
2.在arr原數組操作,從前向后合并arr和brr數組(O(n^2),S(1))
3.在arr原數組操作,從后向前合并arr和brr數組(O(n),S(1))
一、空間換時間
思想:申請一個新空間大小,剛好夠arr和brr數組有效數據存放。將arr和brr數據合并到新空間中,再將新空間數組賦值到arr中。
bool Merge_1(int* arr, int m, int* brr, int n, int arrlen)//m為arr有效數據個數,n為brr有效數據個數,arrlen為arr能夠存儲數據的個數 {if (m + n > arrlen) return false;//arr空間必須足夠存放arr和brr的有效數據int* newdata = (int*)malloc(sizeof(int) * arrlen);if (newdata == NULL) return false;int i = 0;//arr下標int j = 0;//brr下標int k = 0;//newdata下標while (i < m && j < n)//依次將arr和brr中的較小的數據放入到newdata中{newdata[k++] = arr[i] < brr[j] ? arr[i++] : brr[j++];}while (i < m)//如果arr有剩余數據,將arr剩余數據放到newdata后面{newdata[k++] = arr[i++];}while (j < n)//如果brr有剩余數據,將brr剩余數據放到newdata后面{newdata[k++] = brr[j++];}memcpy(arr, newdata, sizeof(int)*arrlen);//將newdata的數據拷貝到arr里面delete newdata;//釋放堆空間return true; }二、將arr和brr的元素從前向后合并到arr中
思想:i和j分別代表arr和brr待合并的數據的第一個數據下標
如果arr[i] <= brr[j],i就像后走,如果遇到arr[i] > brr[j]就將arr的i開始向后的數據向后移一位,將brr[j]賦值到arr[i]中,i++指向arr中待合并的數據的第一位,j++指向brr中下一個待合并的數據。如下圖,arr[i] > brr[j]
如下圖,將arr中的i開始的數據向后移一個單元格:
如下圖,將brr[j]放到arr[i]中:
然后i和j都向后移一位,指向待合并的第一個元素(藍色為已合并,紅色為待合并),如下圖:
重復上面步驟,代碼如下:
三、從后向前合并數組arr和brr
思想:i為arr待合并數據的最后一個元素下標,j為brr待合并數據的最后一個元素下標,k為arr和brr元素合并到arr后,最后一個元素的下標,如下圖:
如果arr[i] >= brr[j],將arr[i]賦值給arr[k],然后k和i都減減;
如果arr[i] < brr[j],將brr[j]賦值給arr[k],然后k和j都減減。
第一次的時候arr[i] == 3, brr[j] == 7,所以將brr[j]賦值給arr[k],然后k和j減減。
如下圖:
然后再比較arr[i]和brr[j]值,重復 以上步驟,到最后:
上面這種情況屬于arr元素都合并完了,brr還剩數據,將brr剩余數據都賦值給arr[k],然后k和j都減減就好了,直到brr合并完。還一種情況屬于i沒有走到頭,但是j走到頭了,說明brr合并完了,那么這個時候就合并完畢。
代碼:
總結
以上是生活随笔為你收集整理的数组——两个有序数组的合并的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 列表初始化和赋值初始化的使用注意事项
- 下一篇: 数组——旋转数组