目錄
1、算法性能
評估一個算法的性能我們首先計算該算法執行語句的次數(包括比較、交換、讀寫數組的次數),同樣我們還需要考慮算法的內存開銷,排序算法一般分爲兩類:除了函數調用所需的棧和固定數目的實例變量之外無需額外內存的原地排序算法,以及需要額外內存空間來存儲另 一份數組副本的其他排序算法。
2、選擇排序
2.1、描述
在長度爲N的無序數組中,第一次遍歷n-1個數,找到最小的數值與第一個元素交換;
第二次遍歷n-2個數,找到最小的數值與第二個元素交換;
。。。
第n-1次遍歷,找到最小的數值與第n-1個元素交換,排序完成。
2.2、特點
- 時間複雜度爲O(N^2) ~(N-1)+(N-2)+...+2+1=N(N-1)/2 ~ N^2/2
- 運行時間和輸入無關(不管輸入的是有序或者無序的,排序所需時間相同)
- 數據移動是最少的.(用了N次交換數據)----------------------------------------------------------------------------------------------------------------優勢
2.3、代碼實現
public class Selection {
public static int[] sort(int[] a) {
int min;
for (int i = 0; i < a.length; i++) {
min = i;
for (int j = i+1; j < a.length; j++) {
if (a[min] > a[j]) {
min = j;
}
}
exch(a, i, min);
}
return a;
}
private static void exch(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static void show(int[] a) {
for (int item:a){
System.out.print(item+",");
}
}
public static void main(String[] args) {
int[] a= {1,3,2,11,22,33,44,55,22,12,11,13,12,15,45,7,8,68,56,43,55,78};
int[] result=sort(a);
show(result);
}
}
3、插入排序
3.1、描述
在要排序的一組數中,假定前n-1個數已經排好序,現在將第n個數插到前面的有序數列中,使得這n個數也是排好順序的。如此反覆循環,直到全部排好順序。
通俗說就是,{1,3,5,2,7,0.....} 假定 1,3,5是排序好的,我們通過將2和這三個數比較,2比5小,和我換一下位置,比3小再換一下位置,直到換到合適的位置。
算法實現裏邊,我們假定j-1個元素是排序好的,每次拿數組裏邊的第j(j=i)個元素和j以前的所有元素比較,交換位置,直到換到自己該待的位置。
3.2、特點
- 時間複雜度爲O(N^2)
- 運行時間與輸入數組的初始順序有關。(對於一些部分有序的數組,該算法有很大的--------------------------------------------優勢)
對於隨機排列的長度爲 N 且主鍵不重複的數組,平均情況下插入排序需要~ N^2/4 次比 較以及~ N^2/4 次交換。最壞情況下需要~ N^2/2 次比較和~ N^2/2 次交換,最好情況下需要 N-1 次比較和 0 次交換。
倒置:是指數組中兩個順序掉到的元素。比如{1,5,3,2} 中的倒置有三對:5-3、5-2、3-2。
插入排序中需要交換元素的次數和倒置的對數是一樣的。需要的比較次數大於等於倒置的 數量,小於等於倒置的數量加上數組的大小再減一。
3.3、代碼實現
public class Insertion {
private static int[] sort(int[] a) {
for (int i = 1; i < a.length; i++) {
for (int j = i; j >0; j--) {
if (a[j] < a[j-1]) {
exch(a,j,j-1);
}else {
break;
}
}
}
return a;
}
private static void exch(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
private static void show(int[] a) {
for (int item:a){
System.out.print(item+",");
}
}
public static void main(String[] args) {
int[] a= {1,3,2,11,22,33,44,55,22,12,11,13,12,15,45,7,8,68,56,43,55,78};
int[] result=sort(a);
show(result);
}
}
4、插入排序的優化
4.1、優化方案
原始方案:{1,3,5,2,7,0.....} 假定 1,3,5是排序好的,我們通過將2和這三個數比較,2比5小,和我換一下位置,比3小再換一下位置,直到換到合適的位置。
優化方案X:{1,3,5,2,7,0.....} 假定1,3,5還是排序好的,我們通過將2和這三個數比較,如果2比5小,5後移到2的位置,2比3小,3後移到原來5的位置,最後,3的位置就空給2 了,最後再把2賦值到3原來的位置上。
優化方案Y:{1,3,5,2,7,0.....} 先把遍歷一邊數組,把最小的元素0一道第一的位置,得到的數組{0,1,3,5,2,7,.....} ,然後再在這個基礎上進行原始方案的排序。
public class Insertion {
static int count = 0;
static int countX = 0;
static int countY = 0;
private static void sort(int[] a) {
for (int i = 1; i < a.length; i++) {
for (int j = i; j > 0; j--) {
if (a[j] < a[j - 1]) {
count++;
exch(a, j, j - 1);
} else {
break;
}
}
show(a);
}
}
private static void sortX(int[] a) {
int N = a.length;
for (int i = 1; i < N; i++) {
int temp = a[i];
int j = i;
for (; j > 0; j--) {
if (temp < a[j - 1]) {
countX++;
a[j] = a[j - 1];
} else {
break;
}
}
a[j] = temp;
show(a);
}
}
public static void sortY(int[] a) {
int N = a.length;
boolean isExchanged = false;
for (int i = N - 1; i > 0; i--) {
if (a[i]<a[i - 1]) {
exch(a, i, i - 1);
countY++;
isExchanged = true;
}
}
show(a);
if (!isExchanged) {
return;
}
for (int i = 2; i < N; i++) {
for (int j = i; a[j]<a[j - 1]; j--) {
exch(a, j, j - 1);
countY++;
}
show(a);
}
}
private static void exch(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
private static void show(int[] a) {
System.out.println("\n");
for (int item : a) {
System.out.print(item + ",");
}
}
public static void main(String[] args) {
int[] a = { 6,4,2,3,1,9,8,7};
show(a);
sort(a);
System.out.println("\n-------------------------");
int[] b = { 6,4,2,3,1,9,8,7};
show(b);
sortX(b);
System.out.println("\n-------------------------");
int[] c = { 6,4,2,3,1,9,8,7};
show(c);
sortY(c);
System.out.println("\n-------------------------");
System.out.println("\ncount=" + count);
System.out.println("\ncountX=" + countX);
System.out.println("\ncountY=" + countY);
}
}
4.2、輸出結果
sort sortX sortY
前面兩種數據的變化是一樣的,最後一種的變化只是先將1移到了第一的位置,其餘的是一樣的,對這三種方法進行萬級的數組測試的話,sortX能比sort快1.7倍左右,sortY比sort快1.5倍作用。變化不是很大, 他們的時間複雜度都是O(N^2)。
本文內容部分來之於《算法》和菜鳥教程,本文主要目的是自己的學習筆記和技術分享。