選擇排序
工作原理是從待排序的數據元素中選出最小(或最大)的一個元素,並與第一個數交換位置,然後選擇剩下數組中最小的數,放到數組的第二個位置,
一次類推。
圖解過程如下:
選擇排序特點是:
1、運行時間和數組內容無關:我們會發現,即使是一個已經排序好的數組去使用選擇排序,運行的時間與隨機的數組排序時間居然一樣長
2、移動的數據少:數組的交換次數和數組大小是線性關係。
/**
* 選擇排序 每次選擇剩下數組中最小的數,然後與剩下數組最前面的數交換位置,直到結束。
*
* @author xiaoqi
*
*/
public class Selection {
public static void sort(int[] a) {
for (int i = 0; i < a.length; i++) {
int min = i;// min爲最小值的下標
//找出剩餘數組的最小值
for (int j = i + 1; j < a.length; j++) {
if(a[min] > a[j]){
min = j;
}
}
//交換位置
int temp = a[i];
a[i] = a[min];
a[min] = temp;
}
}
}
插入排序
插入排序就如同我們打牌一樣,按照順序把每張牌插入一個已經排好序的數組中,剩餘的數組右移即可。
圖解如下:
特點,插入排序所需時間與數組的初識順序相關,通過這點我們知道,它的運行效率是要高於選擇排序的。其比較適合部分有序和規模中小的數組。
/**
* 插入排序 如同打牌一樣,將剩下數組的第一個插入到前面已經排好序的數組中,然後後移插入位置到原位置的數組一位 特別適合有一定順序的數組
*
* @author xiaoqi
*
*/
public class Insertion {
/**
* 將a[i]取出,然後從a[i-1]的位置開始從已經排序好的數組的最後一個位置開始向左(依次到第0個位置)比較,大於就交換位置
*
* 通過交換位置的方式向右移動
* @param a
*/
public static void sort2(int[] a) {
for (int i = 1; i < a.length; i++) {
for (int j = i; j > 0; j--) {
if (a[j] < a[j-1]) {
int temp = a[j-1];
a[j-1] = a[j];
a[j] = temp;
}
}
}
}
}
希爾排序
希爾排序是對插入排序的一種優化。我們知道,插入排序是適合部分有序的數組,這樣就可以使移動的數組儘量的小。而希爾排序就是先把一個數組變成“部分有序”,再進行插入排序,從而得到結果。他的思想是設置一個h,通過插入排序,讓數組中任意間隔h的元素都是有序的,然後縮小h的值,再排序,直到h爲1。因此它的效率取決於h的選取。
圖解:
/**
* 希爾排序 是插入排序的一種改進,它的空間複雜度取決於一個常數因子,但是小於插入排序。
* 思想:把數組分爲間隔爲h的h個數組,然後分別插入排序,再把分爲h/k(k>1)個數組,再插入排序,直到h爲1。
* @author xiaoqi
*
*/
public class Shell {
public static void sort(int[] a){
int N = a.length;
int h = 1;
//假設這個常數因子是 d = 1/3
//先得到一個h/d + 1大於 數組長度的最小值
while(h < N/3){
h = 3 * h + 1;
}
//進行插入排序直到h爲1
while(h >= 1){
//每個數組間隔爲h,進行插入排序
for(int i=h;i< N;i++){
for(int j = i;j >= h;j -= h){
if(a[j] < a[j-h]){
int temp = a[j];
a[j] = a[j-h];
a[j-h] = temp;
}
}
}
//縮小h
h = h /3;
}
SortTest.show();
SortTest.isSorted(a);
}
}