java幾種常用的排序算法

先來看看各種排序方式的區別


直接貼下代碼

package com.panda.sort.bubble;

public class BubbleSort {
	/**
	 * 冒泡排序
	 * @param args
	 */
	static void exchange(int[] array,int a,int b){
		int c =array[a];
		array[a] = array[b];
		array[b] = c;
	}
	public static void main(String[] args) {
		int[] array = new int[]{10,14,15,32,65,25,11,2,5,9,19,27};
		for(int i = 0;i<array.length-1;i++){
			for(int j=i+1;j<array.length;j++){
				if(array[i] > array[j]){
					BubbleSort.exchange(array,i,j);
				}
			}
		}
		for(int i=0;i<array.length;i++){
			System.out.print(array[i]+",");
		}
	}
}
class DirectBubble{
	/**
	 * 冒泡排序升級版,定向冒泡排序,也叫雞尾酒排序
	 * @param args
	 */
	public static void main(String[] args) {
		int[] array = new int[]{10,14,15,32,65,25,11,2,5,9,19,27};
		int left = 0;
		int right = array.length-1;
		while(left < right){
			for(int i = left;i<right;i++){
				if(array[i]>array[i+1]){
					BubbleSort.exchange(array, i, i+1);
				}
			}
			right--;
			for(int i = right;i>left;i--){
				if(array[i-1]>array[i]){
					BubbleSort.exchange(array, i-1, i);
				}
			}
			left++;
			
		}
		for(int i=0;i<array.length;i++){
			System.out.print(array[i]+",");
		}
	}
}

package com.sort;
/**
 * 	時間複雜度:O(n^2) 
 *	空間複雜度:O(1)
 *	最少比較次數:(已排序的數組)n-1次 
 *	最多比較次數:(降序的數組)n(n-1)/2次
 *	賦值操作次數:比較次數-(n-1)
 * 	插入排序不適合對大量數據排序,適合對接近排序的數據排序。
 * 	插入排序是穩定排序。
 * @author Administrator
 *
 */
public class InsertSort {
	public static void main(String[] args) {  
        int[] array = new int[]{10,14,15,32,65,25,11,2,5,9,19,27};  
        for(int i = 1;i<array.length;i++){  
            int a = array[i];  
            int j = i-1;  
            while(j>=0 && array[j]>a){  
                array[j+1] = array[j];  
                j--;  
            }  
            array[j+1] = a;  
        }  
          
        for(int i=0;i<array.length;i++){  
            System.out.print(array[i]+",");  
        }  
    }  
}

package com.sort;
/**
 * 二分(折半)插入(Binary insert sort)排序是一種在直接插入排序算法上進行小改動的排序算法。
 * 其與直接排序算法最大的區別在於查找插入位置時使用的是二分查找的方式,在速度上有一定提升。
 * 但是,在查找二分點的時間上的時間損耗,導致了這個算法並不能比直接插入排序優秀多少,除非你有十分確切的數據大小和隨機訪問迭代器。
 * @author Administrator
 *
 */
public class MiddleSortt {
	public static void main(String[] args) {  
        int[] array = new int[]{10,14,15,32,65,25,11,2,5,9,19,27};  
        int middle,i,j,a,left,right;  
        for(i = 1;i<array.length;i++){  
            a = array[i];  
            left = 0;  
            right = i-1;  
            while(left<=right){  
                middle = (left+right)/2;  
                if(array[middle] > a){  
                        right = middle - 1;  
                }else{  
                        left = middle + 1;  
                }  
            }  
            for (j = i - 1; j >= left; j--){  
                array[j + 1] = array[j];              
            }  
            array[left] = a;   
        }  
        for(int s=0;s<array.length;s++){  
            System.out.print(array[s]+",");  
        }  
    }  
}

package com.sort;
/**
 * 希爾排序
 * 希爾排序,也稱遞減增量排序算法,是插入排序的一種高速而穩定的改進版本。
 * 希爾排序是基於插入排序的以下兩點性質而提出改進方法的:
 * 1、插入排序在對幾乎已經排好序的數據操作時, 效率高, 即可以達到線性排序的效率
 * 2、但插入排序一般來說是低效的, 因爲插入排序每次只能將數據移動一位>
 * @author Administrator
 *
 */
public class ShellSort {
	public static void main(String[] args) {  
        int[] array = new int[]{10,14,15,32,65,25,11,2,5,9,19,27};  
        int i,j,a;  
        int h = 0;  
        while(h<=array.length){  
            h = 3*h+1;  
        }  
        while(h>=1){  
            for(i=h;i<array.length;i++){  
                j = i-h;  
                a = array[i];  
                while((j>=0)&&(array[j]>a)){  
                    array[j+h] = array[j];  
                    j = j-h;  
                }  
                array[j+h] = a;  
            }  
            h = (h-1)/3;  
        }  
          
        for(int s=0;s<array.length;s++){  
            System.out.print(array[s]+",");  
        }  
    }  
}
package com.sort;
/**
 * 選擇排序,它的工作原理如下。首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小元素,
 * 然後放到排序序列末尾。以此類推,直到所有元素均排序完畢。
 * @author Administrator
 *
 */
public class SelectionSort {
	static void exchange(int[] array,int a,int b){  
        int c =array[a];  
        array[a] = array[b];  
        array[b] = c;  
    }  
    public static void main(String[] args) {  
        int[] array = new int[]{10,14,15,32,65,25,11,2,5,9,19,27};  
        for(int i = 0;i<array.length-1;i++){  
            int min=i;  
            for(int j = i+1;j<array.length;j++){  
                if(array[j]<array[min]){  
                    min = j;  
                }  
            }  
            if(min != i){  
                SelectionSort.exchange(array, min, i);  
            }  
        }  
          
        for(int i=0;i<array.length;i++){  
            System.out.print(array[i]+",");  
        }  
    }  
}

package com.sort;
/**
 * 
 * 快速排序是由東尼·霍爾所發展的一種排序算法。在平均狀況下,排序 n 個項目要Ο(n log n)次比較。
 * 在最壞狀況下則需要Ο(n2)次比較,但這種狀況並不常見。事實上,快速排序通常明顯比其他Ο(n log n) 算法更快,
 * 因爲它的內部循環(inner loop)可以在大部分的架構上很有效率地被實現出來,且在大部分真實世界的數據,
 * 可以決定設計的選擇,減少所需時間的二次方項之可能性。
 *步驟:
 *1.從數列中挑出一個元素,稱爲 “基準”(pivot),
 *2.重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。
 *3.在這個分區退出之後,該基準就處於數列的中間位置。這個稱爲分區(partition)操作。
 *  遞歸地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序。
 * @author Administrator
 *
 */
public class QuickSort {
	public static void main(String[] args) {  
        int[] array = new int[]{5,1,6,8,7,4,9,10,2,3};  
        QuickSort.quickSort(0, array.length-1, array);  
           
        for(int i=0;i<array.length;i++){  
            System.out.print(array[i]+",");  
        }  
    }  
    public static void quickSort(int a,int b,int[] array){  
        if(a<b){  
            int x = array[a];  
            int i = a;  
            int j = b;  
            while(i<j){  
                while(i < j && x<=array[j]){  
                    j--;  
                }  
                if(i<j){  
                    array[i] = array[j];  
                }  
                while(i<j && x>=array[i]){  
                    i++;  
                }  
                if(i<j){  
                    array[j] = array[i];  
                }  
            }  
            array[i] = x;  
            quickSort(a,i-1,array);  
            quickSort(i+1,b,array);  
        }  
    }  
}


根據實測這幾種排序方法效率高低依次爲:快速排序>希爾排序>二分法排序>直接插入排序>選擇排序>冒泡排序。

千萬長度數組排序對比,快速排序用時 1 秒,希爾排序用時 2 秒。
十萬長度數組排序對比,二分插入法排序用時 2 秒,直接插入排序用時 3 秒,選擇排序用時 6 秒,冒泡排序用時 14 秒。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章