国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 開發(fā) > Java > 正文

Java經(jīng)典快排思想以及快排的改進(jìn)講解

2024-07-14 08:43:26
字體:
供稿:網(wǎng)友

一.經(jīng)典快排思想

前提條件:給定一個(gè)無序數(shù)組arr

  1. 取這個(gè)數(shù)組最后一個(gè)數(shù) num 作為標(biāo)準(zhǔn),將前面部分的數(shù)分為兩部分,使得<=num的部分在左邊,>num的數(shù)在右邊;
  2. 然后將最后一個(gè)數(shù)和>num部分的第一個(gè)數(shù)進(jìn)行交換,就使得原本在數(shù)組最后位置的num找到了正確的位置,它的左邊都是比它小的以及和它一樣的數(shù),右邊都是比它大的數(shù)
  3. 回到1,進(jìn)行遞歸或迭代,使得所有的數(shù)都找到正確的位

二.通過荷蘭國(guó)旗問題改進(jìn)快排

什么是荷蘭國(guó)旗問題?

已知一個(gè)整形數(shù)組arr,和一個(gè)整數(shù)num,請(qǐng)把小于num的數(shù)放在數(shù)組的左邊,等于num的數(shù)放在數(shù)組的中間,大于num的數(shù)放在數(shù)組的右邊。

解決思路:

遍歷數(shù)組

  • 1. 若比num小,當(dāng)前位置和小于的最后一個(gè)位置+1的值交換,并當(dāng)前位置++;
  • 2. 若比num大,當(dāng)前位置和大于的第一個(gè)位置-1的值交換;
  • 3. 若等于num的值,當(dāng)前位置++;

附上代碼:

public static void NetherlandsFlag(int[] arr, int L, int R, int num) { int i = L; int p1 = L-1; int p2 = R+1; //終止條件:當(dāng)前數(shù)的位置在大于區(qū)的前一個(gè) while(i < p2) {  if(arr[i] < num) {   //當(dāng)前數(shù)比num小,放左邊,i位置上的數(shù)和L上的數(shù)進(jìn)行交換,并且i++,L++   swap(arr, i++, ++p1);  } else if(arr[i] == num) {   //當(dāng)前數(shù)和num相等,i++   i++;  } else {   //當(dāng)前數(shù)比num大,放右邊,i位置上的數(shù)和R上的數(shù)進(jìn)行交換,并且i++,R--   swap(arr, i, --p2);  } }}

我們可以發(fā)現(xiàn),荷蘭國(guó)旗問題和經(jīng)典快排不同的就只是將<=num改為了< num和=num兩部分,借用這個(gè)思想使得原來每次只可以讓一個(gè)數(shù)找到正確的位置改進(jìn)為了每次至少讓一個(gè)數(shù)找到位置。

三.在這基礎(chǔ)上將其改為隨機(jī)快排

隨機(jī)快排改進(jìn)的地方只是在選取數(shù)的時(shí)候,將每次都選取最后位置的數(shù)改為選取隨機(jī)的一個(gè)數(shù)作為num,這樣做的好處是什么呢?

1.選取最后一個(gè)數(shù):如果是一個(gè)已經(jīng)排好序的數(shù)組,每次找到位置之后,左邊是要進(jìn)行排序的部分,數(shù)組長(zhǎng)度是原長(zhǎng)度-1,它的時(shí)間復(fù)雜度就是O(N^2);如果每次找到的數(shù)都是中間的位置,它的時(shí)間復(fù)雜度就只有O(logN)

2.然而以隨機(jī)數(shù)作為選取的標(biāo)準(zhǔn)num的時(shí)候,因?yàn)槭请S機(jī)的,就只能通過數(shù)學(xué)期望去計(jì)算它的時(shí)間復(fù)雜度,時(shí)間復(fù)雜度是O(logN)

下面附上最終的快排代碼及注釋

/* * swap(int[] arr, int i, int j);是將arr數(shù)組的i和j位置上的數(shù)交換的方法 */public static void quickSort(int[] arr) { // 如果為空或長(zhǎng)度為1不需要排序,直接返回 if(arr == null || arr.length < 2)  return; else  quickSort(arr, 0, arr.length - 1);}// 遞歸排序public static void quickSort(int[] arr, int L, int R) { if(L < R) {  /*   * 隨機(jī)快排的隨機(jī)就在這   * 是隨機(jī)選取了一個(gè)數(shù),和 R 進(jìn)行了交換,然后使用這個(gè)數(shù)作為num,   * 所以每次選取的num是隨機(jī)的,   * 在計(jì)算時(shí)間復(fù)雜度時(shí),是沒有最優(yōu)最差情況的   * 而是通過一個(gè)長(zhǎng)期的數(shù)學(xué)期望計(jì)算的,結(jié)果是O(N*logN)   */  swap(arr, L + (int) (Math.random() * (R - L + 1)), R);  int[] border = partition(arr, L, R);  // 小于區(qū)和大于區(qū)進(jìn)行遞歸  quickSort(arr, L, border[0] - 1);  quickSort(arr, border[1] + 1, R); }}// 將給定數(shù)組劃分為小于區(qū)、等于區(qū)和大于區(qū)public static int[] partition(int[] arr, int L, int R) { int num = arr[R]; int less = L - 1; int more = R + 1; int curr = L; // 分為小于區(qū)等于區(qū)和大于區(qū) while(curr < more) {  if(arr[curr] < num) {   swap(arr, curr++, ++less);  } else if(arr[curr] > num) {   swap(arr, curr, --more);  } else {   curr++;  } } //返回等于區(qū)的左右邊界的下標(biāo),通過下標(biāo)確定小于區(qū)和大于區(qū)遞歸時(shí)的參數(shù) return new int[] {less + 1, more - 1};}

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)VeVb武林網(wǎng)的支持。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到JAVA教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 马关县| 贵州省| 彭泽县| 渭南市| 江永县| 丹巴县| 蕉岭县| 临江市| 天水市| 毕节市| 瓦房店市| 祁阳县| 秦皇岛市| 砚山县| 福贡县| 翁源县| 芜湖市| 乌兰察布市| 林口县| 伊金霍洛旗| 航空| 阳江市| 金秀| 安丘市| 霞浦县| 五大连池市| 建宁县| 崇州市| 苏州市| 石首市| 麻城市| 遂平县| 成武县| 德州市| 九江市| 顺义区| 盐亭县| 巍山| 潞西市| 北川| 囊谦县|