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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

泛 归并排序 及 逆序对

發(fā)布時(shí)間:2025/3/20 编程问答 70 豆豆
生活随笔 收集整理的這篇文章主要介紹了 泛 归并排序 及 逆序对 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

今天寫一個(gè)歸并排序的模板,返回值為該序列的逆序?qū)?shù)

?

基本思路

歸并排序就是利用二分的思想,將區(qū)間無限遞歸二分,直到當(dāng)前劃分區(qū)間只包含一個(gè)元素或沒有元素的時(shí)候(我們認(rèn)為這個(gè)序列是自動(dòng)有序的),我們回溯到上一層,然后將當(dāng)前層的左右兩個(gè)區(qū)間合并為一個(gè)有序序列,然后繼續(xù)回溯,回溯之后,當(dāng)前層的左右兩個(gè)區(qū)間都應(yīng)該分別是已經(jīng)經(jīng)過合并的有序子區(qū)間,我們將這兩個(gè)有序子區(qū)間再進(jìn)行有序合并,再返回上一層,直到返回最大區(qū)間,則合并最大區(qū)間的左右有序子區(qū)間,得到有序序列。

流程演示

比如:22 ?3 ?1 ?5 ?4 ?7 ?9 ?1 ?8 ?0

紅色區(qū)間劃分:22 ?3 ?1 ?5 ?4

左邊:22? ?3 ? ? ? 右邊 ? 1 ? 5 ? 4

左邊:合并有序:3 ? 22

右邊:5 ?4區(qū)間遞歸返回時(shí)候變?yōu)?#xff1a;4 5

右邊合并:1 ?4 ?5

左右區(qū)間合并為一個(gè)區(qū)間:1 ?3 ?4 ?5 ?22

至此左側(cè)區(qū)間處理完畢

右側(cè)區(qū)間同理,得到有序序列:0 ?1 ?7 ?8 ?9

最后合并整個(gè)區(qū)間

0 ?1 ?1 ?3 ?4 ?5 ?7 ?8 ?9 ?22

?

逆序?qū)?shù)

我們利用歸并的思想,它會(huì)將每個(gè)區(qū)間細(xì)分到最小,返回整合的時(shí)候,會(huì)進(jìn)行左右區(qū)間合并,合并的時(shí)候就要比較左右區(qū)間當(dāng)前值那個(gè)大,然后取小的那個(gè),我們可以在比較的時(shí)候做記錄,如果左側(cè)的值小于右側(cè),我們就做記錄,這樣一路回溯,就會(huì)找到所有的逆序?qū)?shù)。

我們利用歸并排序的返回值來將此記錄值輸出到外部

?

泛型代碼:

template<typename value_type, typename value_Ptr> int merge_sort(const value_Ptr& begin, const value_Ptr& end) {static std::vector<value_type> to(end - begin);static int cnt{ 0 }; //記錄逆序?qū)?shù)if (end - begin <= 1)return 0;value_Ptr mid = begin + (end - begin) / 2;merge_sort<value_type>(begin, mid);merge_sort<value_type>(mid, end);//將上述兩段區(qū)間順序排列value_Ptr l = begin, r = mid;int k{ 0 }, index{ 0 };while (l < mid && r < end)if (*l < *r)to[k++] = *l++;else //如果左側(cè)值小于右側(cè) {cnt += mid - l; //逆序?qū)?shù)記錄to[k++] = *r++;}while (l < mid)to[k++] = *l++;while (r < end)to[k++] = *r++;for (index = 0; begin + index < end; ++index)*(begin + index) = to[index];return cnt; }

?

測(cè)試與使用

#include <iostream> #include <vector>using namespace std;int main() {ios::sync_with_stdio(false);int list[10]{ 22,3,1,5,4,7,9,1,8,0 };vector<int> v{ list,list + 10 };int cnt = merge_sort<int>(list + 0, list + 10);merge_sort<int>(v.begin(), v.end());for (auto it : v)cout << it << " ";cout << endl;for (auto it : list)cout << it << " ";cout << endl;cout << "逆序?qū)?shù):" << cnt << endl << endl;char list_[10]{ 'r','c','2','A','z','b','8','0','r', '3' };vector<char>v_{ list_,list_ + 10 };cnt = merge_sort<char>(list_ + 0, list_ + 10);merge_sort<char>(v_.begin(), v_.end());for (auto it : v_)cout << it << " ";cout << endl;for (auto it : list_)cout << it << " ";cout << endl;cout << "逆序?qū)?shù):" << cnt << endl << endl; }

?

?

時(shí)間復(fù)雜度為:O(N * log N)

?

感謝您的閱讀,生活愉快~

?

轉(zhuǎn)載于:https://www.cnblogs.com/lv-anchoret/p/9539504.html

總結(jié)

以上是生活随笔為你收集整理的泛 归并排序 及 逆序对的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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