日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数组——两个有序数组的合并

發布時間:2024/4/17 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数组——两个有序数组的合并 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目:有元素按照遞增有序排列的兩個數組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都向后移一位,指向待合并的第一個元素(藍色為已合并,紅色為待合并),如下圖:

重復上面步驟,代碼如下:

//在原數組中操作,從兩個數組的前面開始合并 bool one_move(int* arr, int len, int start,int last)//將下標為[start,last]的元素向后后移一個位置,不考慮last后的數據被覆蓋的問題 {if (start < 0 || start > last || last >= len - 1) return false;for (int i = last; i >= start; i--){arr[i + 1] = arr[i];}return true; }bool Merge_2(int* arr, int m, int* brr, int n, int arrlen) {if (m + n > arrlen) return false;//arr空間必須足夠存放arr和brr的有效數據int i = 0;int j = 0;while (i < m && j < n){if (arr[i] > brr[j])//說明i的位置應該放brr[j],將arr的i開始的數據后移一個位置,i位置放brr[j]{if (one_move(arr, arrlen, i, m - 1) != true)//將arr的下標為[i,m-1]的數據后移一個位置{return false;}arr[i] = brr[j];//將brr[j]的數據放到arr[i]位置上i++;j++;m += 1;//arr有效數據加1}else//說明i的位置就應該還是arr[i]{i++;}}while (j < n)//說明arr的i走到了arr現有有效數據的最后一個位置的后面,將brr剩余的數據直接賦值到i開始向后的位置{arr[i++] = brr[j++];}return true; }

三、從后向前合并數組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合并完了,那么這個時候就合并完畢。
代碼:

//在原數組中操作,從arr和brr的后面開始合并 bool Merge_3(int* arr, int m, int* brr, int n, int arrlen) {if (m + n > arrlen) return false;//arr空間必須足夠存放arr和brr的有效數據int i = m - 1;//arr下標int j = n - 1;//brr下標int k = m + n - 1;//合并后的最后一個元素下標while (j >= 0 && i >= 0)//arr元素先合并完或者brr元素先合并完,那么就退出{arr[k--] = arr[i] > brr[j] ? arr[i--] : brr[j--];}while (j >= 0)//如果brr還剩數據,說明arr合并完了,將brr剩余元素繼續合并到arr前面就好了{arr[k--] = brr[j--];} }

總結

以上是生活随笔為你收集整理的数组——两个有序数组的合并的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。