天天看點

Java排序算法-Java入門|Java基礎課程Java 排序算法1、 課程目标2、适用對象3、相關概念4、算法介紹5、冒泡排序(Bubble Sort)6、選擇排序(Selection Sort)7、插入排序(Insertion Sort)8、希爾排序(Shell Sort)9、歸并排序(Merge Sort)10、快速排序(Quick Sort)11、堆排序(Heap Sort)12、計數排序(Counting Sort)13、桶排序(Bucket Sort)14、基數排序(Radix Sort)

排序是任何語言都會使用到的功能之一,然成果排序的算法有很多,對空間的要求及其時間效率也不盡相同。

本文章以Java語言示例,通過對空間要求、時間效率要求,來對比各種排序算法的使用場景

Java語言初學者

Java算法愛好者

排序,就是使一串記錄,按照其中的某個或某些關鍵字的大小,遞增或遞減的排列起來的操作。

排序算法,就是如何使得記錄按照要求排列的方法。

排序算法在很多領域得到相當地重視,尤其是在大量資料的處理方面。

一個優秀的算法可以節省大量的資源。在各個領域中考慮到資料的各種限制和規範,要得到一個符合實際的優秀算法,得經過大量的推理和分析。

十種常見排序算法可以分為兩大類:

非線性時間比較類排序:通過比較來決定元素間的相對次序,由于其時間複雜度不能突破O(nlogn),是以稱為非線性時間比較類排序。

線性時間非比較類排序:不通過比較來決定元素間的相對次序,它可以突破基于比較排序的時間下界,以線性時間運作,是以稱為線性時間非比較類排序。

Java排序算法-Java入門|Java基礎課程Java 排序算法1、 課程目标2、适用對象3、相關概念4、算法介紹5、冒泡排序(Bubble Sort)6、選擇排序(Selection Sort)7、插入排序(Insertion Sort)8、希爾排序(Shell Sort)9、歸并排序(Merge Sort)10、快速排序(Quick Sort)11、堆排序(Heap Sort)12、計數排序(Counting Sort)13、桶排序(Bucket Sort)14、基數排序(Radix Sort)
Java排序算法-Java入門|Java基礎課程Java 排序算法1、 課程目标2、适用對象3、相關概念4、算法介紹5、冒泡排序(Bubble Sort)6、選擇排序(Selection Sort)7、插入排序(Insertion Sort)8、希爾排序(Shell Sort)9、歸并排序(Merge Sort)10、快速排序(Quick Sort)11、堆排序(Heap Sort)12、計數排序(Counting Sort)13、桶排序(Bucket Sort)14、基數排序(Radix Sort)

穩定:如果a原本在b前面,而a=b,排序之後a仍然在b的前面。

不穩定:如果a原本在b的前面,而a=b,排序之後 a 可能會出現在 b 的後面。

時間複雜度:對排序資料的總的操作次數。反映當n變化時,操作次數呈現什麼規律。

空間複雜度:是指算法在計算機内執行時所需存儲空間的度量,它也是資料規模n的函數。

冒泡排序是一種簡單的排序算法。

它重複地走訪過要排序的數列,一次比較兩個元素,如果它們的順序錯誤就把它們交換過來。

走訪數列的工作是重複地進行直到沒有再需要交換,也就是說該數列已經排序完成。

這個算法的名字由來是因為越小的元素會經由交換慢慢“浮”到數列的頂端。

比較相鄰的元素。如果第一個比第二個大,就交換它們兩個;

對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對,這樣在最後的元素應該會是最大的數;

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

重複步驟1~3,直到排序完成。

動圖來源

Java排序算法-Java入門|Java基礎課程Java 排序算法1、 課程目标2、适用對象3、相關概念4、算法介紹5、冒泡排序(Bubble Sort)6、選擇排序(Selection Sort)7、插入排序(Insertion Sort)8、希爾排序(Shell Sort)9、歸并排序(Merge Sort)10、快速排序(Quick Sort)11、堆排序(Heap Sort)12、計數排序(Counting Sort)13、桶排序(Bucket Sort)14、基數排序(Radix Sort)

選擇排序(Selection-sort)是一種簡單直覺的排序算法。

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,

然後,再從剩餘未排序元素中繼續尋找最小(大)元素,然後放到已排序序列的末尾。

4以此類推,直到所有元素均排序完畢。

n個記錄的直接選擇排序可經過n-1趟直接選擇排序得到有序結果。具體算法描述如下:

初始狀态:無序區為R[1..n],有序區為空;

第i趟排序(i=1,2,3…n-1)開始時,目前有序區和無序區分别為R[1..i-1]和R(i..n)。該趟排序從目前無序區中-選出關鍵字最小的記錄 R[k],将它與無序區的第1個記錄R交換,使R[1..i]和R[i+1..n)分别變為記錄個數增加1個的新有序區和記錄個數減少1個的新無序區;

n-1趟結束,數組有序化了。

Java排序算法-Java入門|Java基礎課程Java 排序算法1、 課程目标2、适用對象3、相關概念4、算法介紹5、冒泡排序(Bubble Sort)6、選擇排序(Selection Sort)7、插入排序(Insertion Sort)8、希爾排序(Shell Sort)9、歸并排序(Merge Sort)10、快速排序(Quick Sort)11、堆排序(Heap Sort)12、計數排序(Counting Sort)13、桶排序(Bucket Sort)14、基數排序(Radix Sort)

插入排序(Insertion-Sort)的算法描述是一種簡單直覺的排序算法。

通過建構有序序列,對于未排序資料,在已排序序列中從後向前掃描,找到相應位置并插入。

一般來說,插入排序都采用in-place在數組上實作。具體算法描述如下:

從第一個元素開始,該元素可以認為已經被排序;

取出下一個元素,在已經排序的元素序列中從後向前掃描;

如果該元素(已排序)大于新元素,将該元素移到下一位置;

重複步驟3,直到找到已排序的元素小于或者等于新元素的位置;

将新元素插入到該位置後;

重複步驟2~5

Java排序算法-Java入門|Java基礎課程Java 排序算法1、 課程目标2、适用對象3、相關概念4、算法介紹5、冒泡排序(Bubble Sort)6、選擇排序(Selection Sort)7、插入排序(Insertion Sort)8、希爾排序(Shell Sort)9、歸并排序(Merge Sort)10、快速排序(Quick Sort)11、堆排序(Heap Sort)12、計數排序(Counting Sort)13、桶排序(Bucket Sort)14、基數排序(Radix Sort)

1959年Shell發明,第一個突破O(n2)的排序算法,是簡單插入排序的改進版。

它與插入排序的不同之處在于,它會優先比較距離較遠的元素。希爾排序又叫縮小增量排序。

先将整個待排序的記錄序列分割成為若幹子序列分别進行直接插入排序,具體算法描述:

選擇一個增量序列t1,t2,…,tk,其中ti>tj,tk=1;

按增量序列個數k,對序列進行k 趟排序;

每趟排序,根據對應的增量ti,将待排序列分割成若幹長度為m 的子序列,分别對各子表進行直接插入排序。僅增量因子為1 時,整個序列作為一個表來處理,表長度即為整個序列的長度。

Java排序算法-Java入門|Java基礎課程Java 排序算法1、 課程目标2、适用對象3、相關概念4、算法介紹5、冒泡排序(Bubble Sort)6、選擇排序(Selection Sort)7、插入排序(Insertion Sort)8、希爾排序(Shell Sort)9、歸并排序(Merge Sort)10、快速排序(Quick Sort)11、堆排序(Heap Sort)12、計數排序(Counting Sort)13、桶排序(Bucket Sort)14、基數排序(Radix Sort)

歸并排序是建立在歸并操作上的一種有效的排序算法。

該算法是采用分治法(Divide and Conquer)的一個非常典型的應用。

将已有序的子序列合并,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。

若将兩個有序表合并成一個有序表,稱為2-路歸并。

把長度為n的輸入序列分成兩個長度為n/2的子序列;

對這兩個子序列分别采用歸并排序;

将兩個排序好的子序列合并成一個最終的排序序列。

Java排序算法-Java入門|Java基礎課程Java 排序算法1、 課程目标2、适用對象3、相關概念4、算法介紹5、冒泡排序(Bubble Sort)6、選擇排序(Selection Sort)7、插入排序(Insertion Sort)8、希爾排序(Shell Sort)9、歸并排序(Merge Sort)10、快速排序(Quick Sort)11、堆排序(Heap Sort)12、計數排序(Counting Sort)13、桶排序(Bucket Sort)14、基數排序(Radix Sort)

實作步驟(分而治之)

分階段可以了解為就是遞歸拆分子序列的過程,遞歸深度為log2n。

Java排序算法-Java入門|Java基礎課程Java 排序算法1、 課程目标2、适用對象3、相關概念4、算法介紹5、冒泡排序(Bubble Sort)6、選擇排序(Selection Sort)7、插入排序(Insertion Sort)8、希爾排序(Shell Sort)9、歸并排序(Merge Sort)10、快速排序(Quick Sort)11、堆排序(Heap Sort)12、計數排序(Counting Sort)13、桶排序(Bucket Sort)14、基數排序(Radix Sort)

治階段,我們需要将兩個已經有序的子序列合并成一個有序序列,比如上圖中的最後一次合并,要将[4,5,7,8]和[1,2,3,6]兩個已經有序的子序列,合并為最終序列[1,2,3,4,5,6,7,8],來看下實作步驟。

Java排序算法-Java入門|Java基礎課程Java 排序算法1、 課程目标2、适用對象3、相關概念4、算法介紹5、冒泡排序(Bubble Sort)6、選擇排序(Selection Sort)7、插入排序(Insertion Sort)8、希爾排序(Shell Sort)9、歸并排序(Merge Sort)10、快速排序(Quick Sort)11、堆排序(Heap Sort)12、計數排序(Counting Sort)13、桶排序(Bucket Sort)14、基數排序(Radix Sort)

通過一趟排序将待排記錄分隔成獨立的兩部分,

其中一部分記錄的關鍵字均比另一部分的關鍵字小,

則可分别對這兩部分記錄繼續進行排序,以達到整個序列有序。

快速排序使用分治法來把一個串(list)分為兩個子串(sub-lists)。具體算法描述如下:

從數列中挑出一個元素,稱為 “基準”(pivot);

重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分區退出之後,該基準就處于數列的中間位置。這個稱為分區(partition)操作;

遞歸地(recursive)把小于基準值元素的子數列和大于基準值元素的子數列排序。

Java排序算法-Java入門|Java基礎課程Java 排序算法1、 課程目标2、适用對象3、相關概念4、算法介紹5、冒泡排序(Bubble Sort)6、選擇排序(Selection Sort)7、插入排序(Insertion Sort)8、希爾排序(Shell Sort)9、歸并排序(Merge Sort)10、快速排序(Quick Sort)11、堆排序(Heap Sort)12、計數排序(Counting Sort)13、桶排序(Bucket Sort)14、基數排序(Radix Sort)

堆排序(Heapsort)是指利用堆這種資料結構所設計的一種排序算法。

堆積是一個近似完全二叉樹的結構,并同時滿足堆積的性質:即子結點的鍵值或索引總是小于(或者大于)它的父節點。

将初始待排序關鍵字序列(R1,R2….Rn)建構成大頂堆,此堆為初始的無序區;

将堆頂元素R[1]與最後一個元素R[n]交換,此時得到新的無序區(R1,R2,……Rn-1)和新的有序區(Rn),且滿足R[1,2…n-1]<=R[n];

由于交換後新的堆頂R[1]可能違反堆的性質,是以需要對目前無序區(R1,R2,……Rn-1)調整為新堆,然後再次将R[1]與無序區最後一個元素交換,得到新的無序區(R1,R2….Rn-2)和新的有序區(Rn-1,Rn)。不斷重複此過程直到有序區的元素個數為n-1,則整個排序過程完成。

Java排序算法-Java入門|Java基礎課程Java 排序算法1、 課程目标2、适用對象3、相關概念4、算法介紹5、冒泡排序(Bubble Sort)6、選擇排序(Selection Sort)7、插入排序(Insertion Sort)8、希爾排序(Shell Sort)9、歸并排序(Merge Sort)10、快速排序(Quick Sort)11、堆排序(Heap Sort)12、計數排序(Counting Sort)13、桶排序(Bucket Sort)14、基數排序(Radix Sort)

計數排序不是基于比較的排序算法,其核心在于将輸入的資料值轉化為鍵存儲在額外開辟的數組空間中。

作為一種線性時間複雜度的排序,計數排序要求輸入的資料必須是有确定範圍的整數。

找出待排序的數組中最大和最小的元素;

統計數組中每個值為i的元素出現的次數,存入數組C的第i項;

對所有的計數累加(從C中的第一個元素開始,每一項和前一項相加);

反向填充目标數組:将每個元素i放在新數組的第C(i)項,每放一個元素就将C(i)減去1。

Java排序算法-Java入門|Java基礎課程Java 排序算法1、 課程目标2、适用對象3、相關概念4、算法介紹5、冒泡排序(Bubble Sort)6、選擇排序(Selection Sort)7、插入排序(Insertion Sort)8、希爾排序(Shell Sort)9、歸并排序(Merge Sort)10、快速排序(Quick Sort)11、堆排序(Heap Sort)12、計數排序(Counting Sort)13、桶排序(Bucket Sort)14、基數排序(Radix Sort)

桶排序是計數排序的更新版。

它利用了函數的映射關系,高效與否的關鍵就在于這個映射函數的确定。

桶排序 (Bucket sort)的工作的原理:假設輸入資料服從均勻分布,将資料分到有限數量的桶裡,每個桶再分别排序(有可能再使用别的排序算法或是以遞歸方式繼續使用桶排序進行排)。

設定一個定量的數組當作空桶;

周遊輸入資料,并且把資料一個一個放到對應的桶裡去;

對每個不是空的桶進行排序;

從不是空的桶裡把排好序的資料拼接起來。

Java排序算法-Java入門|Java基礎課程Java 排序算法1、 課程目标2、适用對象3、相關概念4、算法介紹5、冒泡排序(Bubble Sort)6、選擇排序(Selection Sort)7、插入排序(Insertion Sort)8、希爾排序(Shell Sort)9、歸并排序(Merge Sort)10、快速排序(Quick Sort)11、堆排序(Heap Sort)12、計數排序(Counting Sort)13、桶排序(Bucket Sort)14、基數排序(Radix Sort)

基數排序是按照低位先排序,然後收集;

再按照高位排序,然後再收集;依次類推,直到最高位。

有時候有些屬性是有優先級順序的,先按低優先級排序,再按高優先級排序。

最後的次序就是高優先級高的在前,高優先級相同的低優先級高的在前。

取得數組中的最大數,并取得位數;

arr為原始數組,從最低位開始取每個位組成radix數組;

對radix進行計數排序(利用計數排序适用于小範圍數的特點);

Java排序算法-Java入門|Java基礎課程Java 排序算法1、 課程目标2、适用對象3、相關概念4、算法介紹5、冒泡排序(Bubble Sort)6、選擇排序(Selection Sort)7、插入排序(Insertion Sort)8、希爾排序(Shell Sort)9、歸并排序(Merge Sort)10、快速排序(Quick Sort)11、堆排序(Heap Sort)12、計數排序(Counting Sort)13、桶排序(Bucket Sort)14、基數排序(Radix Sort)