歸併排序和基數排序
- 歸併排序
思想:歸併排序與上述基於交換,選擇排序的思想不一樣。“歸併”的含義是將兩個或兩個以上的有序列表組合成一個新的有序表。嘉定待排序表含有n個記錄,則可以看成是n個有序的字表,每個字表長度為1,然後兩兩歸併,得到n/2個長度為2或1的有序表;再兩兩歸併,…,如此重複,直到合併成一個長度為n的有序表位置,這種排序方法成為2-路歸併排序,如下為歸併排序示例。
Merge()的功能是將前後相鄰的兩個有序表歸併成為一個有序表的演算法。設兩段有序表A[low…mid],A[mid…high]存放在同一順序表中小林的位置上,先將它們複製到輔助陣列B中。每次從對B中的兩個端取出一個記錄進行關鍵字的比較,江較小者放入A中,將陣列B中有一段的下表超出其對應的表長時(即該段的所有元素已經完全複製到A中),將另一段中的剩餘部分直接複製到A中。
- java程式碼實現:
/**
* @author:cch
* @description: 歸併排序
* @date 2020/12/17
*/
public class MergeSort {
public static void main(String[] args) {
int arr[] = { 8, 4, 5, 7, 1, 3, 6, 2 };
mergeSort(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
public static void mergeSort(int[] arr, int l, int r) {
if (l == r) {
return;
}
int mid = l + ((r - l) >> 1);
mergeSort(arr, l, mid);
mergeSort(arr, mid + 1, r);
merge(arr, l, mid, r);
}
private static void merge(int[] arr, int l, int mid, int r) {
int[] help = new int[r + 1 - l];
int i = 0;
int p1 = l;
int p2 = mid + 1;
// 兩邊做比較
while (p1 <= mid && p2 <= r) {
help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
}
// 左邊全部完了
while (p2 <= r) {
help[i++] = arr[p2++];
}
// 右邊全部完了
while (p1 <= mid) {
help[i++] = arr[p1++];
}
for (i = 0; i < help.length; i++) {
arr[l + i] = help[i];
}
}
}
- 效能分析:
空間效率:Merge()操作中,輔助空間剛好要佔用n個單元,所以歸併排序的空間複雜度為O(n)。
時間效率:每一趟歸併的時間複雜度為O(n),共需進行log2n趟歸併,所以演算法的時間複雜度為O(nlog2n)。 - 穩定性:由於Merge()操作不會改變相同關鍵字記錄的相對次序,所以2-路歸併排序演算法是一個穩定得的排序演算法。
- 基數排序
思想:基數排序
是一種很特備的排序方法,他不是基於比較進行排序的,而是採用多關鍵字排序思想(即基於關鍵字各位的帶下進行排序的),藉助“分配”和“收集”兩種操作對單邏輯關鍵字進行排序。技術排序又可以分為最高位優先(MSD)排序和最低位優先(LSD)排序,如下為歸併排序示例。
- java程式碼實現:
/**
* @author:cch
* @description: 基數排序
* @date 2020/12/17
*/
public class RadixSort {
public static void main(String[] args) {
int[] arr = {63, 157, 189, 51, 101, 47, 141, 121, 157, 156,
194, 117, 98, 139, 67, 133, 181, 12, 28, 0, 109};
radixSort(arr);
System.out.println(Arrays.toString(arr));
}
/**
* 高位優先法
*
* @param arr 待排序列,必須為自然數
*/
private static void radixSort(int[] arr) {
//待排序列最大值
int max = arr[0];
int exp;//指數
//計算最大值
for (int anArr : arr) {
if (anArr > max) {
max = anArr;
}
}
//從個位開始,對陣列進行排序
for (exp = 1; max / exp > 0; exp *= 10) {
//儲存待排元素的臨時陣列
int[] temp = new int[arr.length];
//分桶個數
int[] buckets = new int[10];
//將資料出現的次數儲存在buckets中
for (int value : arr) {
//(value / exp) % 10 :value的最底位(個位)
buckets[(value / exp) % 10]++;
}
//更改buckets[i],
for (int i = 1; i < 10; i++) {
buckets[i] += buckets[i - 1];
}
//將資料儲存到臨時陣列temp中
for (int i = arr.length - 1; i >= 0; i--) {
temp[buckets[(arr[i] / exp) % 10] - 1] = arr[i];
buckets[(arr[i] / exp) % 10]--;
}
//將有序元素temp賦給arr
System.arraycopy(temp, 0, arr, 0, arr.length);
}
}
}
相關文章
- 排序(2)--選擇排序,歸併排序和基數排序排序
- [排序] 歸併排序排序
- 快速排序&&歸併排序排序
- 歸併排序求逆序數排序
- 歸併排序排序
- 四、歸併排序 && 快速排序排序
- 計數排序、桶排序和基數排序排序
- 歸併排序--二路排序排序
- 排序演算法__歸併排序排序演算法
- 排序演算法:歸併排序排序演算法
- 歸併排序--排序演算法排序演算法
- 排序演算法 - 歸併排序排序演算法
- 排序演算法——歸併排序排序演算法
- 排序演算法(歸併排序)排序演算法
- php插入排序,快速排序,歸併排序,堆排序PHP排序
- 【Java資料結構與演算法】第八章 快速排序、歸併排序和基數排序Java資料結構演算法排序
- java歸併排序Java排序
- [java]歸併排序Java排序
- 歸併排序模板排序
- 桶排序和基數排序排序
- 327. 區間和的個數 (歸併排序)排序
- 排序演算法之 '歸併排序'排序演算法
- php實現 歸併排序,快速排序PHP排序
- 利用java實現插入排序、歸併排序、快排和堆排序Java排序
- 【分治演算法】歸併排序,快速排序和漢諾塔演算法排序
- O(lgn)的三種排序,快速排序、歸併排序、堆排序排序
- 氣泡排序、歸併排序與快速排序比較排序
- 歸併和快速排序思想的延伸排序
- Python八大演算法的實現,插入排序、希爾排序、氣泡排序、快速排序、直接選擇排序、堆排序、歸併排序、基數排序。Python演算法排序
- 歸併排序 js demo排序JS
- C# 歸併排序C#排序
- 【筆記】歸併排序筆記排序
- 歸併排序例項排序
- 逆序對的數量(歸併排序模板)排序
- ForkJoin和氣泡排序組合實現的歸併排序排序
- 直播系統原始碼,實現快速排序和歸併排序原始碼排序
- 演算法系列(四)排序演算法中篇--歸併排序和快速排序演算法排序
- 演算法:排序連結串列:歸併排序演算法排序