十大排序算法解析
排序:對某一序列對象根據某關鍵字進行排序
穩定性:排序前a在b前面,而a=b,排序後a還在b前面
內排序:所有排序在內存中完成
外排序:由於數據太大,因此將數據放到硬盤中,而排序通過磁盤和內存的數據傳輸才能進行
排序算法 平均時間複雜度 最好情況 最壞情況 空間複雜度 排序方式 穩定性
冒泡排序 O(n^2) O(n) O(n^2) O(1) In-place 穩定
選擇排序 O(n^2) O(n^2) O(n^2) O(1) In-place 不穩定
插入排序 O(n^2) O(n) O(n^2) O(1) In-place 穩定
希爾排序 O(n log n) O(n log^2 n) O(n log^2 n) O(1) In-place 不穩定
歸併排序 O(n log n) O(n log n) O(n log n) O(n) Out-place 穩定
快速排序 O(n log n) O(n log n) O(n^2) O(log n) In-place 不穩定
堆排序 O(n log n) O(n log n) O(n log n) O(1) In-place 不穩定
計數排序 O(n+k) O(n+k) O(n+k) O(k) Out-place 穩定
桶排序 O(n+k) O(n+k) O(n^2) O(n+k) Out-place 穩定
基數排序 O(n+k) O(n+k) O(n+k) O(n+k) Out-place 穩定
n :表示數據範圍
k : "桶"的個數
In-place : 佔用常數內存,不佔用額外內存
Out-place : 佔用額外內存
|——直接插入排序
|——插入排序|
| |——希爾排序
|
| |——簡單選擇排序
|——內部排序(使用內存)|——選擇排序|
| | |——堆排序
| |
| | |——冒泡排序
| |——交互排序|
| | |——快速排序
| |
| |——歸併排序
| |
| |——基數排序
|
|
|——外部排序(內存和外存結合使用)
冒泡排序:
思想:
1 從第一個數開始與一位對比,如果比下一位大(小)將它們位置互換
int[] mm = {2,1,5,7,4}
2,1,5,7,4 --> 1,2,5,7,4 --> 1,2,5,7,4 --> 1,2,5,4,7
2 第一輪排序結束之後,最大(最小)的那位放到了,最後一位,此過程再執行n-1次就可以完成排序
3 在外面嵌套一層for循環控制執行次數
優化:一般最後的某些位已經是排序好了的,不需要再次排序,子循環for可以不進行交換
/**
* 測試冒泡排序算法
* @author Administrator
*
*/
public class BubbleSort {
public static void main(String[] args) throws Exception {
int[] mm = {2,1,5,7,4};
int temp = 0;
int length = mm.length;
for(int j = 1;j<=mm.length;j++) {
for(int i=0;i<mm.length-j;i++) {
if(mm[i]>mm[i+1]) {
temp = mm[i];
mm[i]=mm[i+1];
mm[i+1]=temp;
}
}
}
for (int i : mm) {
System.out.print(i);
}
}
}
快速排序:
思想:
定義第一位爲基準數,同時將第一位和最後一位分別定義爲哨兵i和哨兵j,哨兵j先開始移動,往左方向,找到比基準數小的就停在那裏,然後哨兵i纔開始移動,找到比基準數大的才停在那裏。
初始數據:6 1 2 7 9 3 4 5 10 8 基準數:6
i j
第一輪: 6 1 2 7 9 3 4 5 10 8
i j
然後將i和j所代表的數,位置互換,得到:
6 1 2 5 9 3 4 7 10 8
i j
此時,哨兵j繼續移動,遇到比基準數6小的4,停下來,然後哨兵i開始移動,遇到比基準數大的9,停下來
6 1 2 5 9 3 4 7 10 8
i j
交換位置 6 1 2 5 4 3 9 7 10 8
i j
然後,哨兵j繼續開始移動,遇到3停下來,然後哨兵i開始移動,與哨兵j相遇,然後將基準數6與他們相遇的值3位置互換
3 1 2 5 4 6 9 7 10 8
到目前爲止,第一輪結束,基準數6已經找到他自己的位置了,他左邊的值比他小,他右邊的值比他大,但是,他左右兩邊的數來時亂糟糟
第二輪,6的位置已經定了,不用動,拿出兩個數列 3 1 2 5 4和9 7 10 8,然後再用之前的方法分別對這兩個數列進行處理
對3 1 2 5 4處理完得到:2 1 3 5 4,基準數3 已經歸位,基準數3不動,再次分裂爲兩個數列2 1 和 5 4 ,分別處理,得到1 2 和4 5
對9 7 10 8處理完得到:8 7 9 10,基準數9 已經歸位,基準數9不動,再次分裂爲兩個數列8 7 和 9 10 ,分別處理的到,7 8 和9 10
最後的到數列
1 2 3 4 5 6 7 8 9 10
總的來說,快速排序就是通過確定一位基準數,每輪都將基準數歸位,直到最後一個基準數歸位。採用了“分治”的思想,時間複雜度爲nlogn
/**
* 快速排序測試
* @author Administrator
*
*/
public class QuickSort {
static int t = 0;
static int[] m = {6,1,2,7,9,3,4,5,10,8};
static int temp;
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
QuickSort quickSort = new QuickSort();
quickSort.quick(0,9);
for (int i : m) {
System.out.print(i);
}
System.out.println();
long end = System.currentTimeMillis();
System.out.println(end-start);
}
public static void quick(int left,int right) {
if(left>right)
return ;
//設置基準數
temp = m[left];
//設置哨兵
int i = left;
int j = right;
while(i!=j) {
while(m[j]>=temp&&i<j) {
j--;
}
while(m[i]<=temp&&i<j) {
i++;
}
//當哨兵i和哨兵j還沒相遇
if(i<j) {
//將值進行互換 不使用第三個變量
/*t = m[i];
m[i] = m[j];
m[j] = t;*/
m[i] = m[i]+m[j];
m[j] = m[i]-m[j];
m[i] = m[i]-m[j];
}
}
//當程序跳出while循環時,i和j已經相等,將基準值歸位
t = m[left];
m[left] = m[i];
m[i] = t;
quick(left,i-1);
quick(i+1,right);
}
}
選擇排序(Selection Sort)
選擇排序是最穩定的排序算法,無論什麼數據進行排序,時間複雜度都是n^2 。
思想:先在序列中選擇最小(最大)的數據放到序列的起始位置,然後再從剩餘的序列中選擇最小(最大)的數據放到已排好的序列的末位,以此類推,知道所有數據都是已排好序列。
/**
* 選擇排序
* @author Administrator
*
*/
public class SelectSort {
static int temp;
static int number;
public static void main(String[] args) throws Exception {
int[] m = {6,1,2,7,9,3,4,5,10,8};
int[] s = SelectSort.selectSort(m);
for(int i = 0;i<s.length;i++) {
System.out.print(s[i]);
}
}
public static int[] selectSort(int[] m) {
if(m.length==0)
return m;
for(int i = 0;i<m.length;i++) {
temp = m[i];
number = i;
for(int j=i+1;j<m.length;j++) {
if(temp>m[j]) {
temp = m[j];
number = j;
}
}
int t = m[number];
m[number] = m[i];
m[i] = t;
}
return m;
}
}
插入排序:
思想:拿到當前元素,在已排好序的序列中逐個比較,不合適,將這個位置的數往後挪一位,合適,插入,直至所有的元素插入結束。
/**
* 插入排序
* @author Administrator
*
*/
public class insertSort {
public static void main(String[] args) throws Exception {
int[] m = {6,1,2,7,9,3,4,5,10,8};
insertSort is = new insertSort();
int[] sort = is.Sort(m);
for(int i = 0;i<sort.length;i++) {
System.out.print(sort[i]);
}
}
public int[] Sort(int[] array) {
if(array.length == 0) {
return array;
}
for(int i = 0;i<array.length-1;i++) {
int index = i;
int temp = array[i+1];
while(index>=0&&temp<array[index]) {
array[index+1] = array[index];
index--;
}
array[index+1] = temp;
}
return array;
}
}