java排序算法之冒泡排序和快速排序

總結一下Java排序算法,以便記憶。算法

各種排序的時間複雜度:數組

排序方法 時間複雜度(平均) 時間複雜度(最壞) 時間複雜度(最好) 空間複雜度 穩定性 複雜性
直接插入排序 O(n2)O(n2) O(n2)O(n2) O(n)O(n) O(1)O(1) 穩定 簡單
希爾排序 O(nlog2n)O(nlog2n) O(n2)O(n2) O(n)O(n) O(1)O(1) 不穩定 較複雜
直接選擇排序 O(n2)O(n2) O(n2)O(n2) O(n2)O(n2) O(1)O(1) 不穩定 簡單
堆排序 O(nlog2n)O(nlog2n) O(nlog2n)O(nlog2n) O(nlog2n)O(nlog2n) O(1)O(1) 不穩定 較複雜
冒泡排序 O(n2)O(n2) O(n2)O(n2) O(n)O(n) O(1)O(1) 穩定 簡單
快速排序 O(nlog2n)O(nlog2n) O(n2)O(n2) O(nlog2n)O(nlog2n) O(nlog2n)O(nlog2n) 不穩定 較複雜
歸併排序 O(nlog2n)O(nlog2n) O(nlog2n)O(nlog2n) O(nlog2n)O(nlog2n) O(n)O(n) 穩定 較複雜
基數排序 O(d(n+r))O(d(n+r)) O(d(n+r))O(d(n+r)) O(d(n+r))O(d(n+r)) O(n+r)O(n+r) 穩定 較複雜

 

 

 

1、冒泡排序

一、基本思想

冒泡排序(Bubble Sort)是一種簡單的排序算法。它重複地走訪過要排序的數列,一次比較兩個元素,若是他們的順序錯誤就把他們交換過來。走訪數列的工做是重複地進行直到沒有再須要交換,也就是說該數列已經排序完成。這個算法的名字由來是由於越小的元素會經由交換慢慢「浮」到數列的頂端。ui

 

 

 

二、算法描述

冒泡排序算法的運做以下:spa

①. 比較相鄰的元素。若是第一個比第二個大,就交換他們兩個。
②. 對每一對相鄰元素做一樣的工做,從開始第一對到結尾的最後一對。這步作完後,最後的元素會是最大的數。
③. 針對全部的元素重複以上的步驟,除了最後一個。
④. 持續每次對愈來愈少的元素重複上面的步驟①~③,直到沒有任何一對數字須要比較code

 

三、代碼實現

冒泡排序須要兩個嵌套的循環. 其中, 外層循環移動遊標; 內層循環遍歷遊標及以後(或以前)的元素, 經過兩兩交換的方式, 每次只確保該內循環結束位置排序正確, 而後內層循環週期結束, 交由外層循環日後(或前)移動遊標, 隨即開始下一輪內層循環, 以此類推, 直至循環結束.blog

public static void bubbleSort(int[] arr){ for (int i = arr.length - 1; i > 0; i--) {      //外層循環移動遊標
        for(int j = 0; j < i; j++){    //內層循環遍歷遊標及以後(或以前)的元素
            if(arr[j] > arr[j+1]){ int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; System.out.println("Sorting: " + Arrays.toString(arr)); } } } }

 

2、快速排序(Quick Sort)

一、基本思想

快速排序的基本思想:挖坑填數+分治法。排序

首先選一個軸值(pivot,也有叫基準的),經過一趟排序將待排記錄分隔成獨立的兩部分,其中一部分記錄的關鍵字均比另外一部分的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序。遞歸

 

 

二、算法描述

快速排序使用分治策略來把一個序列(list)分爲兩個子序列(sub-lists)。步驟爲:it

①. 從數列中挑出一個元素,稱爲」基準」(pivot)。io

②. 從新排序數列,全部比基準值小的元素擺放在基準前面,全部比基準值大的元素擺在基準後面(相同的數能夠到任一邊)。在這個分區結束以後,該基準就處於數列的中間位置。這個稱爲分區(partition)操做。

 

③. 遞歸地(recursively)把小於基準值元素的子數列和大於基準值元素的子數列排序。

遞歸到最底部時,數列的大小是零或一,也就是已經排序好了。這個算法必定會結束,由於在每次的迭代(iteration)中,它至少會把一個元素擺到它最後的位置去。

 

三、代碼實現

用僞代碼描述以下:

①. i = L; j = R; 將基準數挖出造成第一個坑a[i]
②.j--,由後向前找比它小的數,找到後挖出此數填前一個坑a[i]中。
③.i++,由前向後找比它大的數,找到後也挖出此數填到前一個坑a[j]中。
④.再重複執行②,③二步,直到i==j,將基準數填入a[i]

/** * 快速排序(遞歸) * * ①. 從數列中挑出一個元素,稱爲"基準"(pivot)。 * ②. 從新排序數列,全部比基準值小的元素擺放在基準前面,全部比基準值大的元素擺在基準後面(相同的數能夠到任一邊)。在這個分區結束以後,該基準就處於數列的中間位置。這個稱爲分區(partition)操做。 * ③. 遞歸地(recursively)把小於基準值元素的子數列和大於基準值元素的子數列排序。 * @param arr 待排序數組 * @param low 左邊界 * @param high 右邊界 */
public static void quickSort(int[] arr, int low, int high){ if(arr.length <= 0) return; if(low >= high) return; int left = low; int right = high; int temp = arr[left];   //挖坑1:保存基準的值
    while (left < right){ while(left < right && arr[right] >= temp){  //坑2:從後向前找到比基準小的元素,插入到基準位置坑1中
            right--; } arr[left] = arr[right]; while(left < right && arr[left] <= temp){   //坑3:從前日後找到比基準大的元素,放到剛纔挖的坑2中
            left++; } arr[right] = arr[left]; } arr[left] = temp;   //基準值填補到坑3中,準備分治遞歸快排
    System.out.println("Sorting: " + Arrays.toString(arr)); quickSort(arr, low, left-1); quickSort(arr, left+1, high); }

說明:快速排序每次交換的元素都有可能不是相鄰的, 所以它有可能打破原來值爲相同的元素之間的順序. 所以, 快速排序並不穩定.

相關文章
相關標籤/搜索