常用的八種排序算法總結

1.冒泡排序

最簡單的一種

public class bubSort {
    public static void main(String[] args) {
        int arr[] = {6,8,5,2,4,5,7};
        for(int i = 0;i < arr.length - 1;i++){
            for(int j = 0;j < arr.length - 1 - i;j++){
                if(arr[j] > arr[j+1]){
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j+1] = temp;
                }
            }
        }
        for(int i = 0;i < arr.length;i++){
            System.out.print(arr[i] + "\t");
        }
    }
}

2.選擇排序

這個和冒泡,插入排序有點類似

/*
 * 選擇排序:每次選擇數組中最大(或最小)的值放在數組的尾部(首部)
 */
public class selectSort {

    public static void main(String[] args) {
        int[] arr = {6,8,2,5,7,4};
        fun(arr);
        System.out.println(Arrays.toString(arr));
    }

    public static void fun(int[] arr){
        if(arr == null || arr.length == 0){
            return;
        }
        for(int i = 0;i < arr.length;i++){
            int index = i;
            for(int j = i + 1;j < arr.length;j++){
                if(arr[j] < arr[index]){
                    index = j;
                }
            }
            int temp=arr[i];
            arr[i]=arr[index];
            arr[index]=temp;
        }
    }
}

3.插入排序

/*
* 插入排序,取出第i+1個元素,與前面的元素一一比較,小的排在前
 */
public class insertSort {

    public static void main(String[] args) {
        int[] arr = {6,8,2,5,7,4};
        inSort(arr);
        System.out.println(Arrays.toString(arr));
    }

    public static void inSort(int[] arr){
        for(int i = 1;i < arr.length;i++){
            for(int j = i;j > 0;j--){
                if(arr[j] < arr[j - 1]){
                    int temp = arr[j];
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                }
            }
        }
    }
}
或者:
public void test3() {
	int i,j,temp;
	for(i=1;i<array.length;i++) {
		temp=array[i];
		for(j=i-1;j>=0;j--) {
			if(temp>array[j]) {
				break;
			}else {
				array[j+1]=array[j];
			}
		}
		array[j+1]=temp;
	}
	System.out.println(Arrays.toString(array));
}

4.歸併排序

public class mergeSort {

    //兩路歸併算法,兩個排好序的子序列合併爲一個子序列
    public static void merge(int []a,int left,int mid,int right){
        int p1,p2,index;
        p1 = left;
        index = left;
        p2 = mid + 1;
        int temp[] = new int[a.length];
        while(p1 <= mid && p2 <= right){
            if(a[p1] <= a[p2]){
                temp[index++] = a[p1++];
            }else{
                temp[index++] = a[p2++];
            }
        }
        while(p1 <= mid){
            temp[index++] = a[p1++];
        }
        while(p2 <= right){
            temp[index++] = a[p2++];
        }
        for (int i = left; i <=right; i++){
            a[i]=temp[i];
        }
    }

    public static void mergeSort(int [] a,int start,int end) {
        if (start < end) {//當子序列中只有一個元素時結束遞歸
            int mid = (start + end) / 2;//劃分子序列
            mergeSort(a, start, mid);//對左側子序列進行遞歸排序
            mergeSort(a, mid + 1, end);//對右側子序列進行遞歸排序
            merge(a, start, mid, end);//合併
        }
    }

    public static void main(String[] args) {
        int[] a = { 49, 38, 65, 97, 76, 13, 27, 50 };
        mergeSort(a, 0, a.length-1);
        System.out.println("排好序的數組:");
        for (int e : a)
            System.out.print(e+" ");
    }
}

5.快速排序

/*
* 既不浪費空間又可以快一點的排序算法
 * 從兩端開始
 */
public class quickSort {
    public static void main(String[] args) {
        int[] arr = {10,7,2,4,7,62,3,4,2,1,8,9,19};
        quickSortCore(arr,0,arr.length - 1);
        for(int num : arr){
            System.out.print(num + "\t");
        }
    }

    public static void quickSortCore(int[] arr,int left,int right){
        int i,j,stand,temp;
        if(left > right){
            return;
        }
        stand = arr[left];
        i = left;
        j = right;
        while (i != j){
            while(i < j && stand <= arr[j]){
                j--;
            }
            while(i < j && stand >= arr[i]){
                i++;
            }
            if(i < j){//注意這個坑,防止與下面的值交換重複
                temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
        arr[left] = arr[i];
        arr[i] = stand;
        quickSortCore(arr,left,j - 1);
        quickSortCore(arr,j + 1,right);
    }
}

6.希爾排序

public class shellSort {

    public static void main(String[] args) {
        int[] arr = {1, 1, 7, 3, 5, 6, 9, 4};
        fun1(arr);

        for (int i : arr) {
            System.out.print(i + "\t");
        }
    }


    //第一種方法
    public static void fun1(int[] data){
        int j = 0;
        int temp = 0;
        for (int increment = data.length / 2; increment > 0; increment /= 2) {
            for (int i = increment; i < data.length; i++) {
                temp = data[i];
                for (j = i - increment; j >= 0; j -= increment) {
                    if (temp < data[j]) {
                        data[j + increment] = data[j];
                    } else {
                        break;
                    }
                }
                data[j + increment] = temp;
            }
        }
    }

    //第二種方法
    public static void fun2(int[] arr){
        for(int step = arr.length / 2;step > 0;step /= 2){
            for(int i = step;i < arr.length;i++){
                int value = arr[i];
                int j;
                //對步長區間中具體的元素進行比較
                for (j = i - step; j >= 0 && arr[j] > value; j -= step) {
                    //j爲左區間的取值,j+step爲右區間與左區間的對應值。
                    arr[j + step] = arr[j];
                }
                System.out.println(j+"...." + (j+step));
                //此時step爲一個負數,[j + step]爲左區間上的初始交換值
                arr[j + step] = value;
            }
        }
    }
}

7.堆排序

堆排序比較複雜推薦去看B站的視頻點擊跳轉
/*
 * 對於堆中的第i個元素,其父元素:(i-1)/2,左子節點:2i+1,右子節點:2i+2
 */
public class heapSort {

    /**
     * 交換節點值
     * @param tree 傳入的樹
     * @param i 較大的值
     * @param j 較小的值
     */
    public static void swap(int[] tree,int i,int j){
        int temp = tree[i];
        tree[i] = tree[j];
        tree[j] = temp;
    }

    /**
     *
     * @param tree 傳入的樹
     * @param n 樹的節點個數
     * @param i 某個節點
     */
    public static void heapExchange(int[] tree,int n,int i){
        if(i >= n){
            return;
        }
        int c1 = 2*i + 1;
        int c2 = 2*i + 2;
        int max = i;
        if(c1 < n && tree[c1] > tree[max]){
            max = c1;
        }
        if(c2 < n && tree[c2] > tree[max]){
            max = c2;
        }
        if(max != i){
            swap(tree,max,i);
            //爲了保證是最大頂堆,交換值後還要和其子節點繼續判斷
            heapExchange(tree,n,max);
        }
    }


    /**
     * 對於一棵深度爲n的樹,從n-1層開始倒序創建最大頂堆
     */
    public static void build_heapTree(int[] tree,int n){
        int lastNode = n - 1;//找到最後一個節點,通過它找到它的父節點
        int parent = (lastNode - 1) / 2;
        for(int i = parent;i >= 0;i--){
            heapExchange(tree,n,i);
        }
    }

    /**
     * 根據創建好的最大頂堆完成排序
     * 思路:對於排好的最大頂堆,把堆頂的元素和最後一個交換,最後一個就是最大的數了,再切去
     *      交換後的已經不是最大頂堆了,需要再排序一下,
     */
    public static void heapSortCore(int[] tree,int n){
        build_heapTree(tree,n);//創建最大頂堆
        for(int i = n - 1;i >= 0;i--){
            swap(tree,i,0);//注意這裏的切去,根據i就是切去後的結果了
            heapExchange(tree,i,0);//從堆頂開始
        }
    }

    public static void main(String[] args) {
        int[] tree = {2,5,3,1,10,4};
        int n = 6;
        heapSortCore(tree,n);
        System.out.println(Arrays.toString(tree));
    }
}

8.基數排序

public class numSort {
    public static void main(String[] args) {
        int[] arr = {23,6,189,45,9,287,56,1,798,34,65,652,5};
        sort(arr);
        System.out.println(Arrays.toString(arr));

    }

    public static void sort(int[] arr){
        int maxNum = Integer.MIN_VALUE;//存放數組中最大的數字
        int[][] arrTemp = new int[10][arr.length];//存放臨時數據的數組,有十個,每個可以存放的最大長度爲arr長度
        int[] counts = new int[10];//用作指針,10個長度對應0~10中每個數字出現的次數,例如counts[2++]對應arrTemp中存放2的位置,從0開始,依次遞加
        for(int i = 0;i < arr.length;i++){//找到最大的數字
            if(arr[i] > maxNum){
                maxNum = arr[i];
            }
        }
        int length = (maxNum+"").length();//求最大數字的長度
        for(int i = 0,n = 1;i < length;i++,n *= 10){//根據長度計算比較次數,n是中間變量,用來取餘
            for(int j = 0;j < arr.length;j++){
                int num = arr[j]/n%10;//除就是截取n的位數後面的數,取模就是取最後一位
                arrTemp[num][counts[num]] = arr[j];
                counts[num]++;
            }
            int index = 0;
            //把存入的數據拿出來
            for(int k= 0;k < counts.length;k++){
                if(counts[k] != 0){//代表有數字
                    //循環取出元素
                    for(int m = 0;m < counts[k];m++){
                        arr[index] = arrTemp[k][m];
                        index++;
                    }
                    //數據拿出來以後置零方便下一次循環用
                    counts[k] = 0;
                }
            }
        }
    }
}

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