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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

递归/分治:归并排序

發(fā)布時間:2023/11/27 生活经验 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 递归/分治:归并排序 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
前言

分治算法:
將一個規(guī)模為N的問題分解為K個規(guī)模較小的子問題,這些子問題相互獨立且與原問題性質(zhì)相同。求出 子問題的解后進行合并,就可得到原問題的解。

步驟如下:

  1. 分解,將要解決的問題劃分成若 干規(guī)模較小的同類問題;
  2. 求解,當子問題劃分得足夠小時 ,用較簡單的方法解決;
  3. 合并,按原問題的要求,將子問題 的解逐層合并構成原問題的解。
歸并排序

在描述歸并排序之前,我們先來看看如何合并兩個有序數(shù)組,大概過程類似與之前描述過的兩個有序鏈表的合并

實現(xiàn)過程如下:

void merge_two_arr(std::vector<int> &arr1, std::vector<int> &arr2, std::vector<int> &result) {int i = 0;int j = 0;/*在下標不斷累加的過程中優(yōu)先插入較小的一個元素,且對應的下標累加*/while(i < arr1.size() && j < arr2.size()) {if (arr1[i] <= arr2[j]) {result.push_back(arr1[i]);i++;} else {result.push_back(arr2[j]);j++;}}if (i == arr1.size()) { //將剩余的未合并的元素合入for (;j < arr2.size(); ++j) {result.push_back(arr2[j]);}} else {for (;i < arr1.size(); ++i) {result.push_back(arr1[i]);}}
}

依據(jù)分治算法的步驟,我們回到歸并排序的過程上

以上過程即實現(xiàn)了分治算法的第三步:合并;

那么分治算法的第一步:分解,第二步:求解該如何做呢?

顯然,我們的一個無序數(shù)組同樣可以不斷得二分,最終拆解為對底層的兩兩合并,對于每一個分解后的集合,我們同樣使用合并有序數(shù)組(因為只有兩個元素了,要做的就是對兩個元素的合并)的過程。

實現(xiàn)如下:

void merge_sort(std::vector<int> &arr) {if (arr.size() < 2) {return ;}int mid = arr.size() / 2;std::vector<int> arr1;std::vector<int> arr2;for (int i = 0; i < mid; ++i) {arr1.push_back(arr[i]);}for (int i = mid; i< arr.size(); ++i){arr2.push_back(arr[i]);}merge_sort(arr1);merge_sort(arr2);arr.clear();/*以上遞歸返回的arr1和arr2為有序數(shù)組,最終合并兩個有序數(shù)組即可*/merge_two_arr(arr1,arr2,arr); 
}

測試代碼如下:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <stdlib.h>using namespace std;
/*合并兩個有序數(shù)組*/
void merge_two_arr(std::vector<int> &arr1, std::vector<int> &arr2, std::vector<int> &result) {int i = 0;int j = 0;while(i < arr1.size() && j < arr2.size()) {if (arr1[i] <= arr2[j]) {result.push_back(arr1[i]);i++;} else {result.push_back(arr2[j]);j++;}}if (i == arr1.size()) {for (;j < arr2.size(); ++j) {result.push_back(arr2[j]);}} else {for (;i < arr1.size(); ++i) {result.push_back(arr1[i]);}}
}
/*歸并排序*/
void merge_sort(std::vector<int> &arr) {if (arr.size() < 2) {return ;}int mid = arr.size() / 2;std::vector<int> arr1;std::vector<int> arr2;for (int i = 0; i < mid; ++i) {arr1.push_back(arr[i]);}for (int i = mid; i< arr.size(); ++i){arr2.push_back(arr[i]);}merge_sort(arr1);merge_sort(arr2);arr.clear();merge_two_arr(arr1,arr2,arr);
}int main(int argc, char const *argv[])
{std::vector<int> arr;int n; cin >> n;int tmp;for (int i = 0; i < n; ++i) {cin >> tmp;arr.push_back(tmp);}	merge_sort(arr);for (int i = 0;i < arr.size(); ++i) {cout << arr[i] << " ";}cout << endl;return 0;
}

輸出如下:

#輸入
5
-7 3 -4 -1 2
#輸出
-7 -4 -1 2 3

總結(jié)

以上是生活随笔為你收集整理的递归/分治:归并排序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。