91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java經典快排思想以及快排的改進講解

發布時間:2020-09-18 07:42:25 來源:腳本之家 閱讀:252 作者:sdr_zd 欄目:編程語言

一.經典快排思想

前提條件:給定一個無序數組arr

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

二.通過荷蘭國旗問題改進快排

什么是荷蘭國旗問題?

已知一個整形數組arr,和一個整數num,請把小于num的數放在數組的左邊,等于num的數放在數組的中間,大于num的數放在數組的右邊。

解決思路:

遍歷數組

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

附上代碼:

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

我們可以發現,荷蘭國旗問題和經典快排不同的就只是將<=num改為了< num和=num兩部分,借用這個思想使得原來每次只可以讓一個數找到正確的位置改進為了每次至少讓一個數找到位置。

三.在這基礎上將其改為隨機快排

隨機快排改進的地方只是在選取數的時候,將每次都選取最后位置的數改為選取隨機的一個數作為num,這樣做的好處是什么呢?

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

2.然而以隨機數作為選取的標準num的時候,因為是隨機的,就只能通過數學期望去計算它的時間復雜度,時間復雜度是O(logN)

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

/*
 * swap(int[] arr, int i, int j);是將arr數組的i和j位置上的數交換的方法
 */
public static void quickSort(int[] arr) {
 // 如果為空或長度為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) {
  /*
   * 隨機快排的隨機就在這
   * 是隨機選取了一個數,和 R 進行了交換,然后使用這個數作為num,
   * 所以每次選取的num是隨機的,
   * 在計算時間復雜度時,是沒有最優最差情況的
   * 而是通過一個長期的數學期望計算的,結果是O(N*logN)
   */
  swap(arr, L + (int) (Math.random() * (R - L + 1)), R);
  int[] border = partition(arr, L, R);
  // 小于區和大于區進行遞歸
  quickSort(arr, L, border[0] - 1);
  quickSort(arr, border[1] + 1, R);
 }
}
// 將給定數組劃分為小于區、等于區和大于區
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;
 // 分為小于區等于區和大于區
 while(curr < more) {
  if(arr[curr] < num) {
   swap(arr, curr++, ++less);
  } else if(arr[curr] > num) {
   swap(arr, curr, --more);
  } else {
   curr++;
  }
 }
 //返回等于區的左右邊界的下標,通過下標確定小于區和大于區遞歸時的參數
 return new int[] {less + 1, more - 1};
}

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對億速云的支持。如果你想了解更多相關內容請查看下面相關鏈接

向AI問一下細節
推薦閱讀:
  1. oracle 快排
  2. 鏈表快排

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

克什克腾旗| 华池县| 德庆县| 开江县| 昭平县| 广丰县| 涟水县| 翁牛特旗| 德令哈市| 嘉鱼县| 灯塔市| 武定县| 青岛市| 甘泉县| 巴林左旗| 灌阳县| 怀仁县| 谷城县| 岚皋县| 宁晋县| 资溪县| 大渡口区| 庆阳市| 西青区| 左云县| 井陉县| 出国| 木里| 平湖市| 大兴区| 环江| 汕尾市| 建平县| 东乌| 博罗县| 鹰潭市| 页游| 双柏县| 宁津县| 永吉县| 旬邑县|