六種常見的排序算法代碼示例

本篇文章僅作為編程語言學(xué)習(xí)的參考案例, 幫助理解排序算法的實(shí)現(xiàn)邏輯, 如有意見或建議請(qǐng)留言.

import java.text.Collator;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Objects;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**

  • @Description: 排序案例

  • @ProjectName: helloworld

  • @ClassName: OrderTest
    */
    public class OrderSortTest {

    /**

    • @description 每次冒泡過程都是從數(shù)列的第一個(gè)元素開始,然后依次和剩
      余的元素進(jìn)行比較,若小于相鄰元素,則交換兩者位置,
    • 同時(shí)將較大元素作為下一個(gè)比較的基準(zhǔn)元素,繼續(xù)將該元素與其相鄰的元素
      進(jìn)行比較,直到數(shù)列的最后一個(gè)元素
    • @param arr
      */
      public static void maopaoSort(int[] arr) {
      // 第一層for循環(huán),用來控制冒泡的次數(shù)
      for (int i = 1; i < arr.length; i++) {
      // 第二層for循環(huán),用來控制冒泡一層層到最后
      for (int j = 0; j < arr.length - 1; j++) {
      // 如果前一個(gè)數(shù)比后一個(gè)數(shù)大,兩者調(diào)換 ,意味著泡泡向上走了一層
      if (arr[j] > arr[j + 1]) {
      int temp = arr[j];
      arr[j] = arr[j + 1];
      arr[j + 1] = temp;
      }
      }
      }
      }

    /**

    • @description 第一點(diǎn)是加入了一個(gè)布爾值,判斷第二層循環(huán)中的調(diào)換有沒有
      執(zhí)行,如果沒有進(jìn)行兩兩調(diào)換,說明后面都已經(jīng)排好序了,
    • 已經(jīng)不需要再循環(huán)了,直接跳出循環(huán),排序結(jié)束.第二點(diǎn)是第二層循環(huán)不再
      循環(huán) 到arr.length - 1,因?yàn)橥饷娴膇循環(huán)遞增一次,
    • 說明數(shù)組最后就多了一個(gè)排好序的大泡泡.第二層循環(huán)也就不需要到最末尾
      一位了,可以提前結(jié)束循環(huán)
    • @param arr
      */
      public static void maopaoSortPlus(int[] arr) {
      if (arr != null && arr.length > 1) {
      for (int i = 0; i < arr.length - 1; i++) {
      // 初始化一個(gè)布爾值
      boolean flag = true;
      for (int j = 0; j < arr.length - i - 1; j++) {
      if (arr[j] > arr[j + 1]) {
      // 調(diào)換
      int temp;
      temp = arr[j];
      arr[j] = arr[j + 1];
      arr[j + 1] = temp;
      // 改變flag
      flag = false;
      }
      }
      if (flag) {
      break;
      }
      }
      }
      }

    /**

    • @description 一次插入排序的操作過程:將待插元素,依次與已排序好的
      子數(shù)列元素從后到前進(jìn)行比較,如果當(dāng)前元素值比待插元素值大,
    • 則將移位到與其相鄰的后一個(gè)位置,否則直接將待插元素插入當(dāng)前元素相
      鄰的后一位置,因?yàn)檎f明已經(jīng)找到插入點(diǎn)的最終位置
    • @param arr
      */
      public static void insertSort(int[] arr) {
      if (arr.length >= 2) {
      for (int i = 1; i < arr.length; i++) {
      // 挖出一個(gè)要用來插入的值,同時(shí)位置上留下一個(gè)可以存新的值的坑
      int x = arr[i];
      int j = i - 1;
      // 在前面有一個(gè)或連續(xù)多個(gè)值比x大的時(shí)候,一直循環(huán)往前面找,
      // 將x插入到這串值前面
      while (j >= 0 && arr[j] > x) {
      // 當(dāng)arr[j]比x大的時(shí)候,將j向后移一位,正好填到坑中
      arr[j + 1] = arr[j];
      j--;
      }
      // 將x插入到最前面
      arr[j + 1] = x;
      }
      }
      }

    /**

    • @description 選擇待排數(shù)列的首部第一個(gè)元素為基準(zhǔn)元素,設(shè)置兩指針,
      分別指向數(shù)列首尾部位置,假設(shè)兩指針分別設(shè)為i和j。每次遍歷的過程是這
      樣的,首先遍歷指針j所指向的元素,直到j(luò)指向的元素值小于基準(zhǔn)元素時(shí),
      停止遍歷,將其與指針i所指向的元素進(jìn)行交換,因?yàn)楫?dāng)前指針?biāo)肝恢镁褪?br> 用于插入較基準(zhǔn)元素小的元素, 然后再將指針i加一。接著輪到指針i遍歷,直
      到i所指向的元素值大于基準(zhǔn)元素時(shí),停止遍歷,將其與指針j所指向的元素
      進(jìn)行交換,之所以可以交換, 是因?yàn)橹羔榡所指向的元素剛剛已經(jīng)交換到前
      半部分呢,故可以直接選擇覆蓋就行,這樣就將大于基準(zhǔn)元素的元素放于后
      半部分。依此類推,直到指針i與指針相等或者大于時(shí),停止外部循環(huán)。最后
      直接將基準(zhǔn)元素直接放置于指針i所指向的位置即可,完成分區(qū)操作。
    • @param arr
    • @param begin
    • @param end
      */
      public static void quickSort(int[] arr, int begin, int end) {
      // 先定義兩個(gè)參數(shù)接收排序起始值和結(jié)束值
      int a = begin;
      int b = end;
      // 先判斷a是否大于b
      if (a >= b) {
      // 沒必要排序
      return;
      }
      // 基準(zhǔn)數(shù),默認(rèn)設(shè)置為第一個(gè)值
      int x = arr[a];
      // 循環(huán)
      while (a < b) {
      // 從后往前找,找到一個(gè)比基準(zhǔn)數(shù)x小的值,賦給arr[a]
      // 如果a和b的邏輯正確--a<b ,并且最后一個(gè)值arr[b]>x,就一直往下找,直到找到后面的值大于x
      while (a < b && arr[b] >= x) {
      b--;
      }
      // 跳出循環(huán),兩種情況,一是a和b的邏輯不對(duì)了,a>=b,這時(shí)候排序結(jié)束.二是在后面找到了比x小的值
      if (a < b) {
      // 將這時(shí)候找到的arr[b]放到最前面arr[a]
      arr[a] = arr[b];
      // 排序的起始位置后移一位
      a++;
      }
      // 從前往后找,找到一個(gè)比基準(zhǔn)數(shù)x大的值,放在最后面arr[b]
      while (a < b && arr[a] <= x) {
      a++;
      }
      if (a < b) {
      arr[b] = arr[a];
      // 排序的終止位置前移一位
      b--;
      }
      }
      // 跳出循環(huán) a < b的邏輯不成立了,a==b重合了,此時(shí)將x賦值回去arr[a]
      arr[a] = x;
      // 調(diào)用遞歸函數(shù),再細(xì)分再排序
      quickSort(arr, begin, a - 1);
      quickSort(arr, a + 1, end);
      }

    /**

    • @description 選擇排序也是一種簡單直觀的排序算法,實(shí)現(xiàn)原理比較直觀
      易懂:首先在未排序數(shù)列中找到最小元素, 然后將其與數(shù)列的首部元素進(jìn)
      行交換,然后,在剩余未排序元素中繼續(xù)找出最小元素,將其與已排序數(shù)列
      的末尾位置元素交換。 以此類推,直至所有元素圴排序完畢
    • @param arr
      */
      public static void selectSort(int[] arr) {
      for (int i = 0; i < arr.length - 1; i++) {
      int min = i; // 遍歷的區(qū)間最小的值
      for (int j = i + 1; j < arr.length; j++) {
      if (arr[j] < arr[min]) {
      // 找到當(dāng)前遍歷區(qū)間最小的值的索引
      min = j;
      }
      }
      if (min != i) {
      // 發(fā)生了調(diào)換
      int temp = arr[min];
      arr[min] = arr[i];
      arr[i] = temp;
      }
      }
      }

    /**

    • @description 歸并排序,簡單的說把一串?dāng)?shù),從中平等分為兩份,再把兩份再細(xì)
      分,直到不能細(xì)分為止,這就是分而治之的分的步驟. 再從最小的單元,兩兩合
      并,合并的規(guī)則是將其按從小到大的順序放到一個(gè)臨時(shí)數(shù)組中,再把這個(gè)臨時(shí)
      數(shù)組替換原數(shù)組相應(yīng)位置,這就是治
    • @param a
    • @param s
    • @param m
    • @param e
      */
      private static void merge(int[] a, int s, int m, int e) {
      // 初始化一個(gè)從起始s到終止e的一個(gè)數(shù)組
      int[] temp = new int[(e - s) + 1];
      // 左起始指針
      int l = s;
      // 右起始指針
      int r = m + 1;
      int i = 0;
      // 將s-e這段數(shù)據(jù)在邏輯上一分為二,l-m為一個(gè)左邊的數(shù)組,r-e為一個(gè)右邊的數(shù)組,兩邊都是有序的
      // 從兩邊的第一個(gè)指針開始遍歷,將其中小的那個(gè)值放在temp數(shù)組中
      while (l <= m && r <= e) {
      if (a[l] < a[r]) {
      temp[i++] = a[l++];
      } else {
      temp[i++] = a[r++];
      }
      }
      // 將兩個(gè)數(shù)組剩余的數(shù)放到temp中
      while (l <= m) {
      temp[i++] = a[l++];
      }
      while (r <= e) {
      temp[i++] = a[r++];
      }
      // 將temp數(shù)組覆蓋原數(shù)組
      for (int n = 0; n < temp.length; n++) {
      a[s + n] = temp[n];
      }
      }

    /**

    • @description 歸并排序
    • @param a
    • @param s
    • @param e
      */
      public static void mergeSort(int[] a, int s, int e) {
      int m = (s + e) / 2;
      if (s < e) {
      mergeSort(a, s, m);
      mergeSort(a, m + 1, e);
      // 歸并
      merge(a, s, m, e);
      }
      }

    /**

    • 獲取一個(gè)打亂的數(shù)組
    • @param arr
      */
      private static int[] getRandomArr(int[] arr) {
      for (int i = 0; i < arr.length; i++) {
      arr[i] = new Random().nextInt(arr.length);
      }
      return arr;
      }

    /**

    • @description 測試

    • @param args
      */
      public static void main(String[] args) {
      int[] arr = new int[200000];
      int[] a = getRandomArr(arr);
      int[] b = a.clone();
      int[] c = b.clone();
      int[] d = b.clone();
      int[] e = b.clone();
      int[] f = b.clone();

      long s = System.currentTimeMillis();
      quickSort(a, 0, a.length - 1);
      System.out.println("快速排序耗時(shí): " + (System.currentTimeMillis() - s) + " 毫秒");

           long s = System.currentTimeMillis();
      

      mergeSort(d, 0, d.length - 1);
      System.out.println("歸并排序耗時(shí): " + (System.currentTimeMillis() - s) + " 毫秒");

           s = System.currentTimeMillis();
      

      selectSort(b);
      System.out.println("選擇排序耗時(shí): " + (System.currentTimeMillis() - s) + " 毫秒");

      s = System.currentTimeMillis();
      insertSort(c);
      System.out.println("插入排序耗時(shí): " + (System.currentTimeMillis() - s) + " 毫秒");

      s = System.currentTimeMillis();
      maopaoSortPlus(e);
      System.out.println("冒泡增強(qiáng)耗時(shí): " + (System.currentTimeMillis() - s) + " 毫秒");

      s = System.currentTimeMillis();
      maopaoSort(f);
      System.out.println("冒泡排序耗時(shí): " + (System.currentTimeMillis() - s) + " 毫秒");

      // 輸出結(jié)果, 查看是否正確
      /for (int i = 0; i < a.length; i++) {
      System.out.print(a[i] + ",");
      }
      System.out.println("");
      for (int i = 0; i < a.length; i++) {
      System.out.print(b[i] + ",");
      }
      System.out.println("");
      for (int i = 0; i < a.length; i++) {
      System.out.print(c[i] + ",");
      }
      System.out.println("");
      for (int i = 0; i < a.length; i++) {
      System.out.print(d[i] + ",");
      }
      System.out.println("");
      for (int i = 0; i < a.length; i++) {
      System.out.print(e[i] + ",");
      }
      System.out.println("");
      for (int i = 0; i < a.length; i++) {
      System.out.print(f[i] + ",");
      }
      /
      }
      }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容