1. 程式人生 > >常用排序演算法:冒泡、選擇、插入排序、希爾排序、歸併排序、堆排序、快排

常用排序演算法:冒泡、選擇、插入排序、希爾排序、歸併排序、堆排序、快排

我們通常所說的排序演算法往往指的是內部排序演算法,即資料記錄在記憶體中進行排序。

排序演算法大體可分為兩種:

一種是比較排序,時間複雜度O(nlogn) ~ O(n^2),主要有:氣泡排序選擇排序插入排序歸併排序堆排序快速排序等。

另一種是非比較排序,時間複雜度可以達到O(n),主要有:計數排序基數排序桶排序等。

這裡我們來探討一下常用的比較排序演算法,非比較排序演算法將在下一篇文章中介紹。下表給出了常見比較排序演算法的效能:

有一點我們很容易忽略的是排序演算法的穩定性(騰訊校招2016筆試題曾考過)。

排序演算法穩定性的簡單形式化定義為:如果Ai = Aj,排序前Ai在Aj之前,排序後Ai還在Aj

之前,則稱這種排序演算法是穩定的。通俗地講就是保證排序前後兩個相等的數的相對順序不變。

對於不穩定的排序演算法,只要舉出一個例項,即可說明它的不穩定性;而對於穩定的排序演算法,必須對演算法進行分析從而得到穩定的特性。需要注意的是,排序演算法是否為穩定的是由具體演算法決定的,不穩定的演算法在某種條件下可以變為穩定的演算法,而穩定的演算法在某種條件下也可以變為不穩定的演算法。

例如,對於氣泡排序,原本是穩定的排序演算法,如果將記錄交換的條件改成A[i] >= A[i + 1],則兩個相等的記錄就會交換位置,從而變成不穩定的排序演算法。

其次,說一下排序演算法穩定性的好處。排序演算法如果是穩定的,那麼從一個鍵上排序,然後再從另一個鍵上排序,前一個鍵排序的結果可以為後一個鍵排序所用。

基數排序就是這樣,先按低位排序,逐次按高位排序,低位排序後元素的順序在高位也相同時是不會改變的。

氣泡排序(Bubble Sort)

氣泡排序是一種極其簡單的排序演算法,也是我所學的第一個排序演算法。它重複地走訪過要排序的元素,依次比較相鄰兩個元素,如果他們的順序錯誤就把他們調換過來,直到沒有元素再需要交換,排序完成。這個演算法的名字由來是因為越小(或越大)的元素會經由交換慢慢“浮”到數列的頂端。

氣泡排序演算法的運作如下:

  1. 比較相鄰的元素,如果前一個比後一個大,就把它們兩個調換位置。

  2. 對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。這步做完後,最後的元素會是最大的數。

  3. 針對所有的元素重複以上的步驟,除了最後一個。

  4. 持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。

由於它的簡潔,氣泡排序通常被用來對於程式設計入門的學生介紹演算法的概念。氣泡排序的程式碼如下:

#include // 分類 -------------- 內部比較排序

// 資料結構 ---------- 陣列

// 最差時間複雜度 ---- O(n^2)

// 最優時間複雜度 ---- 如果能在內部迴圈第一次執行時,使用一個旗標來表示有無需要交換的可能,可以把最優時間複雜度降低到O(n)

// 平均時間複雜度 ---- O(n^2)

// 所需輔助空間 ------ O(1)

// 穩定性 ------------ 穩定

voidSwap(intA[],inti,intj)

{

inttemp = A[i];

A[i] = A[j];

A[j] = temp;

}

voidBubbleSort(intA[],intn)

{

for(intj = 0;j1;j++)// 每次最大元素就像氣泡一樣"浮"到陣列的最後

{

for(inti = 0;i1 - j;i++)// 依次比較相鄰的兩個元素,使較大的那個向後移

{

if(A[i] > A[i + 1])// 如果條件改成A[i] >= A[i + 1],則變為不穩定的排序演算法

{

Swap(A,i,i + 1);

}

}

}

}

intmain()

{

intA[] = {6,5,3,1,8,7,2,4};// 從小到大氣泡排序

intn = sizeof(A) / sizeof(int);

BubbleSort(A,n);

printf("氣泡排序結果:");

for(inti = 0;i)

{

printf("%d ",A[i]);

}

printf("n");

return0;

}

上述程式碼對序列{ 6, 5, 3, 1, 8, 7, 2, 4 }進行氣泡排序的實現過程如下

使用氣泡排序為一列數字進行排序的過程如右圖所示:

儘管氣泡排序是最容易瞭解和實現的排序演算法之一,但它對於少數元素之外的數列排序是很沒有效率的。

氣泡排序的改進:雞尾酒排序

雞尾酒排序,也叫定向氣泡排序,是氣泡排序的一種改進。此演算法與氣泡排序的不同處在於從低到高然後從高到低,而氣泡排序則僅從低到高去比較序列裡的每個元素。他可以得到比氣泡排序稍微好一點的效能。

雞尾酒排序的程式碼如下:

#include // 分類 -------------- 內部比較排序

// 資料結構 ---------- 陣列

// 最差時間複雜度 ---- O(n^2)

// 最優時間複雜度 ---- 如果序列在一開始已經大部分排序過的話,會接近O(n)

// 平均時間複雜度 ---- O(n^2)

// 所需輔助空間 ------ O(1)

// 穩定性 ------------ 穩定

voidSwap(intA[],inti,intj)

{

inttemp = A[i];

A[i] = A[j];

A[j] = temp;

}

voidCocktailSort(intA[],intn)

{

intleft = 0;// 初始化邊界

intright = n - 1;

while(left  right)

{

for(inti = left;i// 前半輪,將最大元素放到後面

{

if(A[i] > A[i + 1

相關推薦

php四種基礎演算法冒泡選擇插入和快速排序法 程式碼練習

function maopao($arr,$len) { for($i=1;$i<$len;$i++) { for($j=0;$j<$len-$i;$j++) { if($arr[$j]>$arr[$j+1])

Java中常見的陣列排序演算法(包括冒泡選擇插入,快速排序)

1 public static void bubbleSort(int[] arr) { 2 3    for(int x=0; x<arr.length-1; x++) { 4 5    for(int y=0; y<arr.length-x-

七大排序演算法冒泡選擇插入,二分法排序,快速,合併,排序)的java實現(14/8/3更新加入二分排序

氣泡排序 思路:就是每次將最大或最小的元素放到陣列的最後,so easy!時間複雜度為(O(n^2)) public class BubbleSort { public static void bubbleSort(int[] a) { for (int j = 1;

常用排序演算法冒泡選擇插入排序排序歸併排序排序

我們通常所說的排序演算法往往指的是內部排序演算法,即資料記錄在記憶體中進行排序。排序演算法大體可分為兩種:一種是比較排序,時間複雜度O(nlogn) ~ O(n^2),主要有:氣泡排序,選擇排序,插入排序,歸併排序,堆排序,快速排序等。另一種是非比較排序,時間複雜度可以達到O

Java三種排序冒泡選擇插入排序

反序 三種 blog void bubble public string length 選擇 三種排序:冒泡,選擇,插入排序 public static void bubbleSort(int[] source){ // 交換

經典排序演算法的實現(選擇插入,shell,,快速,歸併排序

1.選擇排序 //選擇排序 void selectSort(int * arr, int n) { for (int i = 0; i < n - 1; i++) { int min = arr[i]; int minPos = i; for (int j = i

python 排序方式之冒泡選擇插入排序

class SortList(object): '''定義一個類方法,把多種排序方法整合起來''' def __init__(self,items=None): self.items=items def bubble_sort(self,li):

簡單排序演算法時間空間複雜度分析及應用(7)-排序

希爾排序,屬於插入排序的一種,是直接插入排序的加強版。在希爾排序中引入了步長(gap)的概念,然而在插入排序中,步長預設為1。正如我們直接堆插入排序的分析,資料集合的排列順序對插入排序的效率會由很大的

三種常用排序演算法冒泡選擇快速)的Java實現

       學習Java有一陣子了,現在還處於比較初級的水平,能夠把簡單的程式寫對就不錯了,更不用談現在能夠拿Java做什麼了。        學完了兩段網路視訊課程,接下來找本書簡單看看。只要有了一個初步的認識,接下來的東西應該可以更加順利一些。學習程式設計最好的方法就

排序演算法冒泡選擇快速插入

基本資料型別的賦值過程:值傳遞(傳遞的是值得拷貝) 資料交換的三種形式: 不需要第三方變數 a = a+b  b = a-b    a = a-b 引用第三方變數  temp = a  a = b  b = tem

JAVA之各種排序演算法冒泡選擇二分法詳細過程)

掌握演算法是作為程式設計師的基本必備素質,而排序也是各種演算法的基礎,雖說java幫我們封裝好了各種資料型別的排序方法,可是我們還是要知道他的原理,下面我就說幾種常用的演算法及原理; 氣泡排序: 原理:相鄰元素兩兩比較,大的往後放,每一次完畢,最大值出現在了最大索引處; 下面我們

java排序演算法氣泡排序選擇排序插入排序

/** * 氣泡排序 * * 原理 是臨近的數字兩兩進行比較,按照從小到大或者從大到小的順序進行交換, * * 這樣一趟過去後,最大或最小的數字被交換到了最後一位, * * 然後再從頭開始進行兩兩比較交換,直到倒數第二位時結束 * * @author daopinz * */

排序演算法氣泡排序插入排序選擇排序快速排序對比

package com.test; public class T { public static void main(String[] args) { long start = System.currentTimeMillis(); int[] arr1 =

三個簡單排序演算法氣泡排序選擇排序插入排序

以下從基礎開始,逐步詳細複習各個排序演算法。先從三個最基礎最簡單的排序演算法開始。他們分別是氣泡排序、選擇排序、插入排序。以下都是java程式碼,並且認為升序是有序。一、氣泡排序1、程式碼public class Main{//氣泡排序 public static void

[置頂] 找工作知識儲備(3)---從頭說12種排序演算法原理圖解動畫視訊演示程式碼以及筆試面試題目中的應用

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

【python資料結構與演算法】幾種排序演算法氣泡排序快速排序

以下排序演算法,預設的排序結果是從小到大。 一.氣泡排序: 1.氣泡排序思想:越大的元素,就像越大的氣泡。最大的氣泡才能夠浮到最高的位置。 具體來說,即,氣泡排序有兩層迴圈,外層迴圈控制每一輪排序中操作元素的個數——氣泡排序每一輪都會找到遍歷到的元素的最大值,並把它放在最後,下一輪排序時

常用排序演算法直接選擇排序

直接選擇排序演算法思路: 第 1 趟,在待排序記錄 r1 ~ r[n]中選出最小的記錄,將它與 r1 交換;第 2 趟, 在待排序記錄 r2 ~ r[n]中選出最小的記錄,將它與 r2 交換;以此類推,第 i 趟在待排序 記錄 r[i] ~ r[n]中選出最小的記錄,將它與

排序演算法氣泡排序插入排序和快速排序

筆試中經常有排序的演算法題,關於氣泡排序,這裡就不再細講了,具體方法很多種,直接上程式碼: //氣泡排序 (個人實現方法)         static void BubbleSort(int[] dataArray) {     &n

kotlin 基本排序演算法冒泡二分....)與java對比

先還是把這個大神的引用地址貼上,要用到圖片 搞懂基本排序演算法  基本演算法不管是哪種程式都會涉及,只是android用的比較少,很容易忘記,所以能掌握幾種是幾種吧!然而java和kotlin的寫法稍微有點出入。 先來看圖: 懂得理論的話,仔細看還是能看的明

12種排序演算法原理圖解動畫視訊演示程式碼以及筆試面試題目中的應用

0、前言      從這一部分開始直接切入我們計算機網際網路筆試面試中的重頭戲演算法了,初始的想法是找一條主線,比如資料結構或者解題思路方法,將博主見過做過整理過的演算法題逐個分析一遍(博主當年自己學演算法就是用這種比較笨的刷題學的,囧),不過又想了想,演算法這東西,博主自己學的過程中一直深感,基礎