八種排序算法總結(jié)(持續(xù)更新中)

八大排序算法總結(jié)


1. 冒泡排序

  • 思想:元素兩兩進行比較,然后交換位置拉盾,通過兩次層循環(huán)把數(shù)據(jù)排序

  • 優(yōu)點:數(shù)據(jù)量較小的時候桨菜,算法效率較高

  • 缺點:

    1. 時間復(fù)雜度為O(n^2)豁状,當(dāng)數(shù)據(jù)量較大的時候捉偏,效率低下
    2. 可以看到,外層循環(huán)每一次結(jié)束后泻红,實際上是將一個相對最大(最胸睬荨)的數(shù)挑出來了,其他的數(shù)據(jù)雖然相對有序谊路,但依然是無序的讹躯,需要再次比較,因此交換位置其實沒有必要缠劝,我們只需要把最大(最谐碧荨)值的角標(biāo)記下來,當(dāng)一次循環(huán)結(jié)束后惨恭,把制定位置的元素進行交換位置就可以了秉馏。這種排序算法就是選擇排序
    3. 我們可以將整個數(shù)組分成若干個小數(shù)組脱羡,對每個數(shù)組分別進行排序萝究,然后把排好序的數(shù)組在合并起來,因為小數(shù)組的排序性能消耗較小锉罐,因此可以提高效率帆竹,這種排序算法就是快速排序,這實際上是分治思想(分而治之)脓规;
  • 使用場景:當(dāng)數(shù)據(jù)的個數(shù)在[0 , 2^3]之間時栽连,可以使用冒泡排序,因為在該種情況下侨舆,實際上進行不了幾次比較秒紧;

  • 注意事項:

    • 兩處優(yōu)化:
        1. 隨著比較的趟數(shù)增加,數(shù)據(jù)會逐漸有序起來态罪,而且數(shù)組后面的元素是有序的噩茄,因此這部分?jǐn)?shù)據(jù)可以退出排序,因此內(nèi)層循環(huán)可以通過控制要比較的元素的個數(shù)來達到這個目的复颈,即j < array.length - 1 - i绩聘;
        1. 當(dāng)比較的趟數(shù)還沒有結(jié)束且數(shù)據(jù)已經(jīng)是有序的時候沥割,就不需要通過排序了,這個時候直接結(jié)束循環(huán)即可凿菩,那么可以通過一個標(biāo)記flag來達到這個目的机杜,如果內(nèi)層循環(huán)在一次循環(huán)過程中,里面的if判斷語句沒有執(zhí)行衅谷,就表示數(shù)據(jù)已經(jīng)是有序的椒拗,因此就可以跳出循環(huán)了。
  • 代碼實現(xiàn)

      public void bubbleSort(int[] array) {
          if (array == null || array.length == 0) {
              throw new IllegalArgumentException();
          }
    
          //外層控比較的趟數(shù)
          for (int i = 0; i < array.length - 1; i++) {//有多少個元素就需要比較多少趟
              //內(nèi)層控制比較的次數(shù)获黔,每一次循環(huán)結(jié)束都會有一個最大(最惺纯痢)值出現(xiàn)在數(shù)組的最后一個角標(biāo)的位置
              //因此這個元素可以退出排序,從而減少內(nèi)層循環(huán)的次數(shù)
              boolean flag = true;
              for (int j = 0; j < array.length - 1 - i; j++) {
                  //從小到大排序
                  if (array[j] > array[j + 1]) {
                      int temp = array[j];
                      array[j] = array[j + 1];
                      array[j + 1] = temp;
                      flag = false;
                  }
              }
              //如果整個內(nèi)層循環(huán)里面的比較都沒有執(zhí)行玷氏,就表明所有的數(shù)字就是有序的堵未,可以不用再進行排序了,直接跳出循環(huán)
              if (flag) {
                  break;
              }
          }
      }
    

2. 快速排序

  • 思想:對冒泡排序的優(yōu)化盏触,

    • 基本思想:通過一趟排序?qū)⒋庞涗浄指畛瑟毩⒌膬刹糠稚罚渲幸徊糠钟涗浀年P(guān)鍵字均比另一部分記錄的關(guān)鍵字小,則可以分別對這兩部分記錄繼續(xù)進行排序赞辩,以達到整個序列有序雌芽。
    • 典型的分治思想,因為有遞歸調(diào)用辨嗽,所以是二叉樹的前序遍歷世落;
    • 分治思想:將一個大的問題分解成幾個小問題,然后對各個小問題各個擊破召庞,最后將所有子問題合并岛心,最終得到母問題的解。因此遞歸也是分治思想篮灼。但需要注意的是忘古,這里不是分類討論的思想;
  • 優(yōu)點:數(shù)據(jù)量大且是線性結(jié)構(gòu)時诅诱,效率較高髓堪;

  • 缺點:

    1. 算法不穩(wěn)定,有大量重復(fù)數(shù)據(jù)時娘荡,性能不好干旁;
    2. 單向鏈?zhǔn)浇Y(jié)構(gòu)處理性能不好(一般來說,鏈?zhǔn)蕉疾皇褂每焖倥判颍?/li>
  • 使用場景:數(shù)據(jù)量大并且是線性結(jié)構(gòu)(數(shù)組)炮沐,當(dāng)時鏈?zhǔn)浇Y(jié)構(gòu)時不要使用這種排序算法争群,JDK中Arrays里面的排序算法就是快速排序Collections.sort(int[] arr)實際上調(diào)用的就是Arrays里面的排序算法大年。

  • 實現(xiàn)步驟:

    1. 先進行一次快速排序换薄,將數(shù)組分割成兩部分玉雾,使得左邊的數(shù)比指定位置的數(shù)小,右邊的數(shù)比指定的位置的數(shù)大轻要;
      1. 任取一個位置的元素(一般都選待排數(shù)組的第一個元素)作為樞軸复旬,同時給待排數(shù)組的第一個元素標(biāo)記為low稀蟋,最后一個元素標(biāo)記為high搬泥,設(shè)樞軸記錄的關(guān)鍵字pivotKey缴淋;
      2. 將所有關(guān)鍵字比樞軸小的記錄都安置在他的位置之前封锉,將所有關(guān)鍵字比樞軸大的記錄都排在他的位置之后,(由此可以將該“樞軸”記錄最后所落得位置i作為分界線吞歼,使待排數(shù)組分成兩個子數(shù)組)漠魏;
        • 具體做法:
          1. 首先從high所指位置起向前搜索浩淘,找到第一個關(guān)鍵字小于pivotKey的記錄咳焚,并且和樞軸記錄互相交換洽损;
          2. 然后從low所指位置起向后搜索庞溜,找到第一個關(guān)鍵字大于pivotKey的記錄革半,然后和樞軸記錄互相交換;
          3. 重復(fù)第一第二步流码,直至low=high為止又官;
    2. 完成第一步后,分別對左邊的數(shù)組和右邊的數(shù)組遞歸進行排序漫试;
  • 代碼實現(xiàn)

      public void quickSort(int[] arr, int begin, int end) {
          if (end - begin <= 0) {
              return;
          }
          //從右相左開始
          boolean isFromRight = true;
          int low = begin;
          int high = end;
          int pivotKey = arr[begin];
          //先從high開始
          L1:
          while (high > low) {
              //從右往左開始
              if (isFromRight) {
                  for (int i = high; i > low; i--) {
                      //要求:pivotKey關(guān)鍵字右邊的數(shù)都比pivotKey大
                      if (arr[i] <= pivotKey) {
                          //如果右邊的比pivotKey小六敬,就交換位置,注意這里不是交換兩個元素
                          arr[low++] = arr[i];
                          high = i;
                          //交換之后,從相反的順序開始
                          isFromRight = !isFromRight;
                          continue L1;
                      }
                  }
                  //只有當(dāng)右邊的數(shù)都比pivotKey大的時候驾荣,才會走到這里來
                  high = low;
              } else {
                  for (int i = low; i < high; i++) {
                      if (arr[i] >= low) {
                          arr[high--] = arr[i];
                          low = i;
                          isFromRight = !isFromRight;
                          continue L1;
                      }
                  }
                  low = high;
              }
          }
          //第一次快速排序結(jié)束外构,將最后找到的值放入中間,即pivotKey
          arr[low]=pivotKey;//因為此時low已經(jīng)等于high播掷,所以寫誰都一樣
    
          //對左邊的數(shù)組進行排序
          quickSort(arr,begin,low-1);
          //對右邊的數(shù)組進行排序
          quickSort(arr,high+1,end);
      }
    

3. 選擇排序

  • 思想

  • 優(yōu)點

  • 缺點

  • 使用場景

  • 代碼實現(xiàn)

3. 歸并排序

4. 希爾排序

6. 插入排序

7. 堆排序

8. 基數(shù)排序(鏈?zhǔn)交鶖?shù)排序)

9. 二分查找算法

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末审编,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子歧匈,更是在濱河造成了極大的恐慌垒酬,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件件炉,死亡現(xiàn)場離奇詭異勘究,居然都是意外死亡,警方通過查閱死者的電腦和手機斟冕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進店門口糕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人磕蛇,你說我怎么就攤上這事景描∪保” “怎么了?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵伏伯,是天一觀的道長橘洞。 經(jīng)常有香客問我,道長说搅,這世上最難降的妖魔是什么炸枣? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮弄唧,結(jié)果婚禮上适肠,老公的妹妹穿的比我還像新娘。我一直安慰自己候引,他們只是感情好侯养,可當(dāng)我...
    茶點故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著澄干,像睡著了一般逛揩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上麸俘,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天辩稽,我揣著相機與錄音,去河邊找鬼从媚。 笑死逞泄,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拜效。 我是一名探鬼主播喷众,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼紧憾!你這毒婦竟也來了到千?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤稻励,失蹤者是張志新(化名)和其女友劉穎父阻,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體望抽,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡加矛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了煤篙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斟览。...
    茶點故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖辑奈,靈堂內(nèi)的尸體忽然破棺而出苛茂,到底是詐尸還是另有隱情已烤,我是刑警寧澤,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布妓羊,位于F島的核電站胯究,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏躁绸。R本人自食惡果不足惜裕循,卻給世界環(huán)境...
    茶點故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望净刮。 院中可真熱鬧剥哑,春花似錦、人聲如沸淹父。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽暑认。三九已至困介,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間穷吮,已是汗流浹背逻翁。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留捡鱼,地道東北人。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓酷愧,卻偏偏與公主長得像驾诈,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子溶浴,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,876評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問題, 分享了一些自己做題目的經(jīng)驗乍迄。 張土汪:刷leetcod...
    土汪閱讀 12,748評論 0 33
  • 最常見的七大排序算法,整理了下士败,包括時間復(fù)雜度和空間復(fù)雜度都做一個詳細的解說闯两,希望對需要的人能有所幫助。 /** ...
    PapiAP閱讀 351評論 0 2
  • 總結(jié)一下常見的排序算法谅将。 排序分內(nèi)排序和外排序漾狼。內(nèi)排序:指在排序期間數(shù)據(jù)對象全部存放在內(nèi)存的排序。外排序:指在排序...
    jiangliang閱讀 1,354評論 0 1
  • 中毒了!真的中毒了隅熙!難受死了稽煤! 不受控制核芽,我已經(jīng)不是我!為什么這樣的酵熙!這世界真的很神奇轧简!我一直從意識...
    玲兒2007閱讀 149評論 0 0
  • 其實提起興趣也不過才幾個月,大多都是一開始時刻想著畫匾二,后來慢慢就想不起來了吉懊,喜歡上微博的很多水彩大觸,其實我最喜歡...
    苗條條biu閱讀 579評論 3 5