比較
名稱 | 數據對象 | 穩定性 | 時間複雜度 | 額外空間複雜度 | 描述 | |
---|---|---|---|---|---|---|
平均 | 最壞 | |||||
冒泡排序 | 數組 | {\displaystyle O(n^{2})} | {\displaystyle O(1)} | (無序區,有序區)。 從無序區通過交換找出最大元素放到有序區前端。 | ||
選擇排序 | 數組 | {\displaystyle O(n^{2})} | {\displaystyle O(1)} | (有序區,無序區)。 在無序區裏找一個最小的元素跟在有序區的後面。對數組:比較得多,換得少。 | ||
鏈表 | ||||||
插入排序 | 數組、鏈表 | {\displaystyle O(n^{2})} | {\displaystyle O(1)} | (有序區,無序區)。 把無序區的第一個元素插入到有序區的合適的位置。對數組:比較得少,換得多。 | ||
堆排序 | 數組 | {\displaystyle O(n\log n)} | {\displaystyle O(1)} | (最大堆,有序區)。 從堆頂把根卸出來放在有序區之前,再恢復堆。 | ||
歸併排序 | 數組 | {\displaystyle O(n\log ^{2}n)} | {\displaystyle O(1)} | 把數據分爲兩段,從兩段中逐個選最小的元素移入新數據段的末尾。 可從上到下或從下到上進行。 | ||
{\displaystyle O(n\log n)} | {\displaystyle O(n)+O(\log n)} 如果不是從下到上 | |||||
鏈表 | {\displaystyle O(1)} | |||||
快速排序 | 數組 | {\displaystyle O(n\log n)} | {\displaystyle O(n^{2})} | {\displaystyle O(\log n)} | (小數,基準元素,大數)。 在區間中隨機挑選一個元素作基準,將小於基準的元素放在基準之前,大於基準的元素放在基準之後,再分別對小數區與大數區進行排序。 | |
希爾排序 | 數組 | {\displaystyle O(n\log ^{2}n)} | {\displaystyle O(n^{2})} | {\displaystyle O(1)} | 每一輪按照事先決定的間隔進行插入排序,間隔會依次縮小,最後一次一定要是1。 | |
計數排序 | 數組、鏈表 | {\displaystyle O(n+m)} | {\displaystyle O(n+m)} | 統計小於等於該元素值的元素的個數i,於是該元素就放在目標數組的索引i位(i≥0)。 | ||
桶排序 | 數組、鏈表 | {\displaystyle O(n)} | {\displaystyle O(m)} | 將值爲i的元素放入i號桶,最後依次把桶裏的元素倒出來。 | ||
基數排序 | 數組、鏈表 | {\displaystyle O(k\times n)} | {\displaystyle O(n^{2})} | 一種多關鍵字的排序算法,可用桶排序實現。 |
希爾排序
定義
- 插入排序在對幾乎已經排好序的數據操作時,效率高,即可以達到線性排序的效率。
- 但插入排序一般來說是低效的,因爲插入排序每次只能將數據移動一位。
基本思想
代碼實現
/*
* 希爾排序
*/
public class ShellSort {
/**
* 排序方法
*/
public static void sort(long[] arr) {
//初始化一個間隔
int h = 1;
//計算最大間隔
while(h < arr.length / 3) {
h = h * 3 + 1;
}
while(h > 0) {
//進行插入排序
long tmp = 0;
for(int i = h; i < arr.length; i++) {
tmp = arr[i];
int j = i;
while(j > h - 1 && arr[j - h] >= tmp) {
arr[j] = arr[j - h];
j -= h;
}
arr[j] = tmp;
}
//減小間隔
h = (h - 1) / 3;
}
}
}
快速排序
簡介
思路分析
下標 | 0 | 1 | 2 | 3 | 4 | 5 |
數據 | 6 | 2 | 7 | 3 | 8 | 9 |
下標 | 0 | 1 | 2 | 3 | 4 | 5 |
數據 | 3 | 2 | 7 | 6 | 8 | 9 |
下標 | 0 | 1 | 2 | 3 | 4 | 5 |
數據 | 3 | 2 | 6 | 7 | 8 | 9 |
下標 | 0 | 1 | 2 | 3 | 4 | 5 |
數據 | 3 | 2 | 6 | 7 | 8 | 9 |
代碼實現
/*
* 快速排序
*/
public class QuickSort {
/**
* 劃分數組
*/
public static int partition(long arr[],int left, int right,long point) {
int leftPtr = left - 1;
int rightPtr = right;
while(true) {
//循環,將比關鍵字小的留在左端
while(leftPtr < rightPtr && arr[++leftPtr] < point);
//循環,將比關鍵字大的留在右端
while(rightPtr > leftPtr && arr[--rightPtr] > point);
if(leftPtr >= rightPtr) {
break;
} else {
long tmp = arr[leftPtr];
arr[leftPtr] = arr[rightPtr];
arr[rightPtr] = tmp;
}
}
//將關鍵字和當前leftPtr所指的這一個進行交換
long tmp = arr[leftPtr];
arr[leftPtr] = arr[right];
arr[right] = tmp;
return leftPtr;
}
public static void sort(long[] arr, int left, int right) {
if(right - left <= 0) {
return;
} else {
//設置關鍵字
long point = arr[right];
//獲得切入點,同時對數組進行劃分
int partition = partition(arr, left, right, point);
//對左邊的子數組進行快速排序
sort(arr,left,partition - 1);
//對右邊的子數組進行快速排序
sort(arr,partition + 1, right);
}
}
}