手寫常用演算法(插入,希爾,快排),java實現
阿新 • • 發佈:2018-12-09
在排序演算法的複習當中,有些演算法還是比較難理解的,好在以前打下的基礎,再次學習輕鬆很多,下面記錄下手寫常用的排序演算法。
直接插入排序的效能分析:
時間複雜度: 1. 最好情況:O(n) 2. 平均情況:O(n^2) 3. 最壞情況:O(n^2) 空間複雜度:O(1) 穩定性:穩定(相同元素的相對位置不會改變)
希爾排序(第一個突破O(n^2)的排序演算法)的效能分析:
會根據增量的不同而不同,一般來說: 時間複雜度: 1. 最好情況:O(n^1.3) 2. 最壞情況:O(n^2) 空間複雜度:O(1) 穩定性:不穩定(相同元素的相對位置會改變)
快速排序的效能分析:
時間複雜度: 1. 最好情況:O(nlog2(n)) 2. 平均情況:O(nlog2(n)) 3. 最壞情況:O(n^2) 空間複雜度:O(log2(n)) 穩定性:不穩定(相同元素的相對位置會改變)
public class Sorts { /** * 插入排序 * @param a */ public static void InsertSort(int[] a) { if (a==null || a.length<=0) { //排空 System.out.println("陣列為空"); return ; } int temp=0; //暫存要插入的元素 int j=0; for (int i = 1,len=a.length; i <len; i++) { //遍歷陣列 temp=a[i]; j=i-1; for (; j>=0 && a[j]>temp;j--) { //如果a[i]之前的數比要插入的temp大,該數後移。注意j>=0 a[j+1]=a[j]; } a[j+1]=temp; //當迴圈結束,也就是temp比a[j]大或者相等,或者最小時(j=-1),插入到a[j]後面 } } /** * 希爾排序 * @param a */ public static void shellSort(int[] a) { if (a==null || a.length<=0) { //排空 System.out.println("陣列為空"); return ; } int temp=0; //暫存要插入的元素 int len=a.length; int j=0; for (int d = len/2; d>0; d/=2) { //取d/2來分割排序記錄 for (int i = d; i<len; i++) {//從d開始,迴圈到結束 temp=a[i]; j=i-d; //取第前d個元素作為比較 for (; j>=0 && a[j]>temp; j-=d) { //連續以d為分割比較 a[j+d]=a[j]; } a[j+d]=temp; //插入 } } } /** * 氣泡排序改進版 * @param a */ public static void bubbleSort(int[] a) { int exchange=a.length-1; int bound=0; while (exchange!=0) { bound=exchange; exchange=0; for (int i = 0; i < bound; i++) { if (a[i]>a[i+1]) { a[i]=a[i]+a[i+1]; a[i+1]=a[i]-a[i+1]; a[i]=a[i]-a[i+1]; exchange=i; } } } } /** * 快速排序演算法 * @param a * @param first * @param end */ public static void quickSort(int[] a,int first,int end) { if (first<end) { int pivot=partition(a, first, end); //開始對區間進行排序,返回最終的軸值 quickSort(a, first, pivot-1); //遞迴排序左區間,軸值不需要參與排序 quickSort(a, pivot+1, end); //遞迴排序右區間 } } /** * 快速排序一次劃分演算法 * @param a * @param first * @param end * @return */ public static int partition(int a[],int first,int end) { int i=first,j=end; while (i<j) { while (i<j && a[j]>=a[i]) { //從右側開始掃描,直到找到右側的比左側小的數,然後交換位置 j--; } if (i<j) { //交換位置 a[i]=a[i]+a[j]; a[j]=a[i]-a[j]; a[i]=a[i]-a[j]; i++; } while (i<j && a[j]>=a[i]) { //從左側開始掃描,直到找到右側的比左側小的數,然後交換位置 i++; } if (i<j) { //交換位置 a[i]=a[i]+a[j]; a[j]=a[i]-a[j]; a[i]=a[i]-a[j]; j--; } } return i; //軸值記錄的最終位置 } public static void main(String[] args) { int[] a = {3, 5, 1, 2, 6, 4, 7, 11, 23, 44, 3, 34}; InsertSort(a); System.out.print("直接插入排序:"); for(int i = 0; i < a.length; i++) { System.out.print(a[i] + " "); } System.out.println(); int[] b={3, 5, 1, 2, 6, 4, 7, 11, 23, 44, 3, 34}; shellSort(b); System.out.print("希爾排序:"); for(int i = 0; i < b.length; i++) { System.out.print(b[i] + " "); } System.out.println(); int[] c={3, 5, 1, 2, 6, 4, 7, 11, 23, 44, 3, 34}; bubbleSort(c); System.out.print("氣泡排序改進版:"); for(int i = 0; i < c.length; i++) { System.out.print(c[i] + " "); } System.out.println(); int[] d={3, 5, 1, 2, 6, 4, 7, 11, 23, 44, 3, 34}; quickSort(d, 0, d.length-1); System.out.print("快速排序:"); for(int i = 0; i < d.length; i++) { System.out.print(d[i] + " "); } } }