歸併和快速排序思想的延伸

2021-09-11 12:06:32 字數 2594 閱讀 3646

前面學習了歸併和快速排序演算法,現在來了解歸併和快速排序演算法背後的演算法思想:分治思想,並對歸併和快速排序進行擴充套件,解決經典演算法問題:逆序對和第k大的演算法問題

顧名思義,分而治之,就是將原問題,分割成同等結構的子問題,之後將子問題逐一解決後,原問題也就得到了解決。

對於乙個長度為n的整數序列a,滿足i < j 且 ai > aj.的數對(i,j)稱為整數序列a的乙個逆序。 通常逆序對可以表示乙個數列的順序程度,從小到大的數列逆序對為0,從大到小的逆序對為:(n*(n-1))/2;

採用分而治之的思想,要求整個數列的逆序對,可以先求出前一半數列的逆序對,和後一半數列的逆序對,然後加上前乙個數列和後乙個數列所形成的逆序對,因為前後兩個數列都是有序,直接在歸併排序merge的時候求是非常簡單的。

function

merge

(&$arr, $l, $mid, $r)

elseif ($j > $r) elseif($tmp[$i] <= $tmp[$j])else

} return $res;

}/**

* [__mergesort 對區間為[l,r]的元素進行歸併排序]

* @param [type] $arr [description]

* @param [type] $l [description]

* @param [type] $r [description]

* @return [type] [description]

*/function

__inversioncount

(&$arr, $l, $r)

$mid = (int)(($l + $r) / 2);

// 求出 arr[l...mid] 範圍的逆序數

$res1 = __inversioncount($arr, $l, $mid);

// 求出 arr[mid+1...r] 範圍的逆序數

$res2 = __inversioncount($arr, $mid+1, $r);

return $res1 + $res2 + merge($arr, $l, $mid, $r);

}function

inversioncount

(&$arr, $n)

複製**

結果

array

( [0] => 3

[1] => 0

[2] => 5

[3] => 5

[4] => 8

[5] => 0

[6] => 8

[7] => 5

)逆序對的個數: 7

複製**

這裡我們採用第三種解法,時間複雜度為:o(n)+o(1/2)+o(1/4)+...+o(1/n), 當n為無窮大時候,時間複雜度約為o(n)

//對arr[l...r]部分進行partition操作

// 返回p,使得arr[l...p-1] < arr[p] ; arr[p+1...r] > arr[p]

function

partition

(&$arr, $l, $r)

} swap($arr, $l, $j);

return $j;

}/**

* [__quicksort 對陣列arr[l...r]進行快速排序]

* @param [type] &$arr [description]

* @param [type] $l [description]

* @param [type] $r [description]

* @return [type] [description]

*/function

__selectk

(&$arr, $l, $r, $k)

// 如果 k == p, 直接返回arr[p]

$p = partition($arr, $l, $r, $k);

if ($p == $k) elseif($p > $k)else

}// 尋找arr陣列中第k小的元素

function

selectk

(&$arr, $n, $k)

複製**

結果

array

( [0] => 9

[1] => 4

[2] => 10

[3] => 4

[4] => 7

[5] => 6

[6] => 3

[7] => 10

[8] => 7

[9] => 9

)第3小的數為: 6

複製**

-------------------------華麗的分割線--------------------

看完的朋友可以點個喜歡/關注,您的支援是對我最大的鼓勵。

個人部落格番茄技術小棧和掘金主頁

快速 歸併和基數排序

快速排序 public class quicksort while arr r pivot if l r temp arr l arr l arr r arr r temp if arr l pivot if arr r pivot if l r if leftif right l public c...

歸併排序 快速排序 分治思想

蒟蒻來水一篇博文方便複習參考 快速排序的基本原理 隨機選擇乙個基點,將比基點大的元素放在基點左側,將比基點小的元素放在基點右側。然後再分別只看基點左側和右側,重複上述過程。由於其利用了分治思想,在平均狀態下其時間複雜度為o nlogn 基本 如下 includeusing namespace std...

歸併和sort排序簡單運用

今天學習了歸併排序和sort函式的簡單運用,感覺sort函式真的是無比的神奇,能加各種神奇的東西,然後進行一些排序練習 歸併排序基本 include using namespace std void merge int data,int start,int end,int result while ...