c++分治法求最大最小值實現_程序員:算法導論,分治法、歸并排序,偽代碼和Java實現...

分治法

我們首先先介紹分治法。分治法的思想:將原問題分解為幾個規模較小但類似于原問題的子問題,遞歸地求解這些子問題,然后在合并這些子問題的解來解決原問題的解。

還是拿撲克牌舉例子,假設桌上有兩堆牌面朝上的牌(牌面朝上:有值),每堆都已排序,最小的牌在頂上。我們希望把這兩堆牌合并成單一的排好序的輸出堆,牌面朝下地放在桌上。應該怎么做呢?

我們的做法是:在牌面朝上的兩堆牌的頂上兩張牌中選取較小的一張,將該牌從其堆中移開(該堆的頂上將顯示一張新牌)并牌面朝下地將該牌放置到輸出堆。重復這個步驟直到兩堆牌都沒有牌。

下面我們來實現上面所提的思想

為了避免在某個基本步驟必須檢查是否有堆為空。在每個堆的底部放置一張哨兵牌,它包含一個特殊的值(很大的值,使它不可能是較小的牌,除非兩個堆都已顯露出其哨兵牌。一旦發生這種情況,說明非哨兵牌都已被放置到輸出堆),用于簡化代碼。

偽代碼:

MERGE(A,p,q,r)

n1 = q - p + 1

n2 = r - q

//L[1..n1+1] and R[1..n2+1]是新的數組

for i = 1 to n1

L[i] = A[p + i -1]

for j = 1 to n2

R[j] = A[q + j]

L[n1 + 1] = ∞

R[n2 + 1] = ∞

i = 1

j = 1

for k = p to r

if L[i] <= R[j]

A[k] = L[i]

i = i + 1

else

A[k] = R[j]

j = j + 1

Java實現:

public void Merge(int[] A,int p,int q,int r){

int n1 = q - p + 1;

int n2 = r - q;

//L[1..n1+1] and R[1..n2+1]是新的數組

int[] L = new int[n1 + 1];

int[] R = new int[n2 + 1];

for (int i = 0;i < n1;i++){

L[i] = A[p + i];

}

for (int j = 0;j < n2;j++){

R[j] = A[q + j + 1];

}

L[n1] = Integer.MAX_VALUE;

R[n2] = Integer.MAX_VALUE;

int i = 0,j = 0;

for (int k = p;k <= r;k++){

if (L[i] <= R[j]){

A[k] = L[i];

i = i + 1;

}else{

A[k] = R[j];

j = j + 1;

}

}

}

下面我們來看一下分治法的步驟

對數組A[2,4,7,1,3,6]調用Merge(A,0,2,5)

初始狀態

c847ee41d458b210c29c8aeec56d81f4.png

初始完L和R數組之后,現在進入for循環階段。讓L中i所指的值和R數組中j所指的值進行比較,把較小的值放入數組A中k所指的位置。并且讓較小的值的索引i或j前進一格(+1)。因為L和R數組已經從小到大排好序了,所以找出來的最小值一定是當前L和R數組的最小值,放入了數組A中也是排好序的,所以讓k前進一步,k=k+1,然后執行下一次循環。

第一此循環:i和j初始為0,k=p=0,讓L[0]與R[0]進行比較 L[0]>R[0]所以R[0]是較小值,把A[0]替換為R[0]。讓j=j+1,i保持不變。k=k+1=1,開啟下一次循環。本次循環結果如下圖所示:

A中的灰色位置包含將被覆蓋的值,L和R中的灰色位置包含有待于被復制回A的值,A中的黃色位置包含它們的最終值,L和R中的黃色位置包含已被復制回A的值。

30d066f439610cd503f7f5097114164e.png

第二次循環:此時i=0,j=1,k=1,讓L[i]和R[j]進行比較,L[0]

30fc750bcef46812212a6a62c5499cf5.png

第三次循環:此時i=1,j=1,k=2,讓L[i]和R[j]進行比較,L[1]>R[1],所以R[1]是較小值,把A[2]即A[2]替換為R[1]。讓j=j+1,i保存不變。k=k+1=3,開啟下一次循環。本次循環結果如下圖所示:

81a1ce1e518a09456531853b8e0dcdc4.png

第四次循環:此時i=1,j=2,k=3,讓L[i]和R[j]進行比較,L[1]

74fdbfc605eabe7f798e7475b8153bd9.png

第五次循環:此時i=2,j=2,k=4,讓L[i]和R[j]進行比較,L[2]>R[2],所以R[2]是較小值,把A[k]即A[4]替換為R[2]。讓j=j+1,j保存不變。k=k+1=4,開啟下一次循環。本次循環結果如下圖所示:

91c009640290e508426aba155db1c5f2.png

注意:此時j已經到達了R數組的最后一個數∞,L數組中的每個數都比∞小,即不等式L[i]>R[j]恒成立。所以不管L剩下多少個數,都會按照順序放置A中,直到i也達到了最后一個數∞,此時k>r,循環已經全部結束。

第六次循環:此時i=2,j=3,k=5,讓L[i]和R[j]進行比較,L[2]

377e73b42ad8edaca37c0445acee62cb.png

第七次循環,此時i=2,j=3,k=6,我們的r=5,判斷條件k<=r為false,循環結束。

分治法的應用——歸并排序

上面講到了分治法,分治法有個很大的限制就是L和R是排好序的才可以。但是許多數組都是很亂的順序。那么怎么解決這個問題呢?試想一下如果L和R數組的大小為1,那么L和R數組肯定是排好序的。對的!我們可以把一個大的數組遞歸拆分成小的子數組,子數組在遞歸拆分成更小的子數組。直到遞歸到的L和R數組的大小為1時,調用MERGE分治法。隨著算法自底向上地推進:合并只含1項的序列對形成長度為2的排好序的序列,合并長度為2的序列對形成長度為4的排好序的序列,依次下去,直到長度為n/2的兩個序列被合并最終形成長度為n的排好序的序列,數組最終會排序完成。

如下圖所示

b9fdd5b687f9d0f0a773573c461b5d1d.png

我們可以把上面提到的MERGE作為歸并排序算法中的一個子程序來用。

下面的過程MERGE-SORT(A,p,r)排序子數組A[p…r]中的元素。若p>=r,則該子數組最多有一個元素,所以已經排好序。否則,分解步驟簡單地計算一個下標q,將A[p…r]分成兩個子數組A[p…q]和A[q+1…r],前者包含?n/2?個元素,后者包含?n/2?個元素。

偽代碼:

MERGE-SORT(A,p,r)

if p < r

q = ?(p+r)/2?

MERGE-SORT(A,p,q)

MERGE-SORT(A,q+1,r)

MERGE(A,p,q,r)

java實現:

public void MergeSort(int[] A,int p,int r) {

if (p < r){

int q =(int)Math.floor((p+r)/2);

MergeSort(A,p,q); //將左半邊排序

MergeSort(A,q+1,r); //將右半邊排序

Merge(A,p,q,r); //歸并結果

}

}

下面我們來看一下歸并排序在數組A=[5,2,4,7,1,3,2,6]上的操作,隨著算法自底向上地推進,待合并的已排好序的各序列的長度不斷增加。

60a38b8e601cbede4deb9673075893c1.png

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/258856.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/258856.shtml
英文地址,請注明出處:http://en.pswp.cn/news/258856.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

菜根譚#82

風來疏竹&#xff0c;風過而竹不留聲&#xff1b;雁度寒潭&#xff0c;雁去而潭不留影&#xff1b;故君子事來而心始現&#xff0c;事去而心隨空。 轉載于:https://www.cnblogs.com/star4knight/p/3604403.html

解讀ASP.NET 5 MVC6系列(9):日志框架

解讀ASP.NET 5 & MVC6系列&#xff08;9&#xff09;&#xff1a;日志框架 原文:解讀ASP.NET 5 & MVC6系列&#xff08;9&#xff09;&#xff1a;日志框架框架介紹 在之前的.NET中&#xff0c;微軟還沒有提供過像樣的日志框架&#xff0c;目前能用的一些框架比如Log4N…

2017第18周四

繼續加班中&#xff0c;很多事不如預期。時間花費很多但效果不成比例。越忙落下的事越多&#xff0c;有時候還需要讓自己靜下來想想&#xff0c;到底有什么是重要的。集中精力放在重要的哪些事&#xff0c;盡自己最大努力即可&#xff0c;盡最大努力即使沒有達到也可以沒有遺憾…

halcon相關的鏈接

論壇、培訓 halcon學習網&#xff1a;http://www.ihalcon.com/鳥叔機器視覺&#xff1a;http://bbs.szvbt.com/forum.php 博客 韓兆新的博客園majunfuLife and Codingzhaojun的博客風韻無聲騎螞蟻上高速的博客小馬_xiaoLV2小新識圖程序園-程序員的世界章柯淵的博客 注&…

[轉]Java8-本地緩存

這里我將會給大家演示用ConcurrentHashMap類和lambda表達式實現一個本地緩存。因為Map有一個新的方法可以在key為Null的時候自動計算一個新的value值。非常完美的實現cache。來看下代碼&#xff1a; public static void main(String[] args) {for (int i 0; i < 10; i)Syst…

python opencv圖像處理程序_Python-OpenCV學習(四):基本圖像處理

轉載請注明出處&#xff1a;danscarlett的博客園 參考資料&#xff1a; 目錄&#xff1a; 讀取 imread 顯示 imshow 存儲 imwrite 縮放 resize 加邊框 copyMakeBorder 裁剪 img[x_start:x_end,y_start:y_end] 1.圖像讀取&#xff1a; cv2.imread(fileName,flagsNone) 函數功能&…

Java進程占用CPU資源過多分析

問題描述&#xff1a; 生產環境下的某臺tomcat7服務器&#xff0c;在剛發布時的時候一切都很正常&#xff0c;在運行一段時間后就出現CPU占用很高的問題&#xff0c;基本上是負載一天比一天高。 問題分析&#xff1a; 1&#xff0c;程序屬于CPU密集型&#xff0c;和開發溝通過&…

分針網——怎么輕松學習JavaScript

js給初學者的印象總是那么的“雜而亂”&#xff0c;相信很多初學者都在找輕松學習js的途徑。我試著總結自己學習多年js的經驗&#xff0c;希望能給后來的學習者探索出一條“輕松學習js之路”。js給人那種感覺的原因多半是因為它如下的特點&#xff1a;A&#xff1a;本身知識很抽…

MATLAB中floor、round、ceil、fix區別

Matlab取整函數有: fix, floor, ceil, round.具體應用方法如下&#xff1a;fix朝零方向取整&#xff0c;如fix(-1.3)-1; fix(1.3)1;floor&#xff0c;顧名思義&#xff0c;就是地板&#xff0c;所以是取比它小的整數&#xff0c;即朝負無窮方向取整&#xff0c;如floor(-1.3)-2…

python時間序列分析航空旅人_用python做時間序列預測一:初識概念

利用時間序列預測方法&#xff0c;我們可以基于歷史的情況來預測未來的情況。比如共享單車每日租車數&#xff0c;食堂每日就餐人數等等&#xff0c;都是基于各自歷史的情況來預測的。 什么是時間序列&#xff1f; 時間序列&#xff0c;是指同一個變量在連續且固定的時間間隔上…

解決mysql不能遠程登入的問題

mysql遠程不能登入&#xff0c;問題就在于當時設置的賬號只限制本地訪問&#xff0c;mysql默認也只是本地訪問。之前的設置&#xff1a; 通過命令行登錄管理MySQL服務器&#xff08;提示輸入密碼時直接回車&#xff09;&#xff1a; mysql> /usr/local/webserver/mysql/bin/…

ASCII碼、HEX、字符、BCD 等等 基礎知識思考

每每遇到這些問題就要想個半天&#xff0c;想不明白還不舒服&#xff0c;今天特別把所想整理下避免以后再次進入思想漩渦&#xff01;&#xff01;&#xff01;計算機存儲和傳輸都是以字節為單位 1 bit 1 二進制數據 1 byte 8 bit 1 字母 1 by…

[Logstash-input-redis] 使用詳解

2019獨角獸企業重金招聘Python工程師標準>>> Redis插件參數配置詳解 工作流程 logstash啟動redis插件redis插件獲取參數&#xff0c;進行校驗工作判斷監聽模式(list,channel,pattern_channel等)&#xff0c;根據不同的監聽模式創建監聽任務創建redis實例&#xff0c…

雅可比旋轉求解對稱二維矩陣的特征值和特征向量

問題描述&#xff1a; 給定一個矩陣&#xff0c;如下&#xff1a; A[a11a21a12a22]A=\begin{bmatrix} a_{11}&a_{12}\\ a_{21}& a_{22} \end{bmatrix} 其中滿足a12a21.也就是所謂的 對稱矩陣。那么如何求解此矩陣的特征值以及特征向量呢&#xff1f;這里我們要用到 …

游戲場景燈光烘焙

【LV4】北京 天殺神(153478394) 10:21:15可能是我找的截圖不好 我就是想問下 一般要烘焙這樣的一個場景的步驟是什么 【LV5】北京地編&#xff5e;mr(274380109) 10:21:44首先就看原畫的色調 確定一個環境光如果是晴天 就打一個直光 給陰影 直光不要太亮 【LV5】北京地編&a…

python畫圖數據的平均值怎么算的_Python氣象數據處理與繪圖(2):常用數據計算方法...

對于氣象繪圖來講&#xff0c;第一步是對數據的處理&#xff0c;通過各類公式&#xff0c;或者統計方法將原始數據處理為目標數據。 按照氣象統計課程的內容&#xff0c;我給出了一些常用到的統計方法的對應函數&#xff1a; import numpy as np 平均值 在計算氣候態&#xff0…

Linux下nginx安裝與配置

部分Linux發布版的默認安裝已經集成了nginx&#xff0c;查看方法ls /usr/local&#xff0c;若已有nginx文件夾說明已集成。nginx依賴庫pcre與zlib&#xff0c;且pcre依賴于gcc與gcc-c&#xff0c;因此安裝步驟為&#xff1a;安裝gcc與gcc-c庫安裝pcre庫安裝zlib庫安裝nginx詳細…

java 讀取properties文件

1.不在項目中讀取 Properties properties new Properties();BufferedReader read new BufferedReader(new InputStreamReader(new FileInputStream("文件的路徑"),"utf-8"));properties.load(read);properties .getProperty("那個文件的key") …

幾種字符串加密解密的方法

為什么80%的碼農都做不了架構師&#xff1f;>>> 第一種&#xff1a;〔 Python 與 Bash Shell 的結合 〕 這個命令會讓你輸入一個字符串&#xff0c;然后會再輸出一串加密了的數字。 加密代碼[照直輸入]: python -c print reduce(lambda a,b: a*256ord(b), raw_inpu…

java delegate怎么寫_美團面試官:你說你們公司的Mybatis分頁插件是你寫的,給我說說它的設計原理?...

來源&#xff1a;http://my.oschina.net/zudajun大多數框架&#xff0c;都支持插件&#xff0c;用戶可通過編寫插件來自行擴展功能&#xff0c;Mybatis也不例外。我們從插件配置、插件編寫、插件運行原理、插件注冊與執行攔截的時機、初始化插件、分頁插件的原理等六個方面展開…