常見排序算法Java實現及複雜度總結

1、冒泡排序

public class SortAlgorithm {
    //1、冒泡排序bubbleSort
    public static void bubbleSort(int[] num){
        int len = num.length;
        for(int i =len-1; i>0;i--){
            for(int j=0; j<=i-1;j++){
                if(num[j]>num[j+1]){
                    swap(num,j,j+1);
                }
            }
        }

    }
    public static void swap(int[] a,int i,int j){
        int temp = a[i];
        a[i]=a[j];
        a[j]=temp;
    }

3、插入排序

public static void insertSort(int[] arr){
        /*
        * 思路:從第二個數開始,把當前數字插入前面已經排序好的數組中,從拍好序的數組的尾部開始,如果數組中元素大於當前
        * 數,那麼把數組中的數向後挪一位,知道找到當前數字合適的位置
        * */
        int temp;
        int len = arr.length;
        for(int i = 1; i<len;i++){
            int j=i-1;
            temp = arr[i];

            while(j>=0){
                if(arr[j]>temp){
                    arr[j+1] = arr[j];
                    j--;
                }
                else{
                    break;
                }
            }
            j++;
            arr[j] = temp;
        }
    }

4、堆排序

public static void heapSort(int[] arr){
        /*
        * 思路:首先要對用數組創建一個最大堆,然後把第一個數和最後一個數交換,然後對第一個數
        * 到倒數第二個數調整順序,創建新的最大堆,然後把新的第一個數和倒數第二個數交換,以此類推
        * */
        int len = arr.length;
        for(int parent = (len-1)/2; parent>=0;parent--){
            adjustHeap(arr,parent,len);
        }
        int lastLeaf = len-1;

        while(lastLeaf>=1){
           // System.out.println("lastLeaf:" + lastLeaf);
            swap(arr,0,lastLeaf);
            /*
            for(int parent = (lastLeaf-1)/2; parent>=0;parent--){
                adjustHeap(arr,parent,lastLeaf);
            }*/
            adjustHeap(arr,0,lastLeaf);
            lastLeaf--;
        }


    }
    public static void adjustHeap(int[] arr, int parent,int len){
        /*
        * 思路:從最後一個父節點開始,如果有子節點大於父節點,那麼把子節點和父節點交換,
        * 直到交換到葉子結點,然後對前一個父節點執行上述動作,直到對根節點執行完此操作
        * */
       // int len = arr.length;
        while((parent*2+1)<len){
            int left = parent*2+1;
            if(parent*2+2<len){
                int right = parent*2+2;
                if(arr[left]<arr[right]){
                    swap(arr,left,right);
                }
            }
            //System.out.println(left);
            if(arr[parent]<arr[left]){
                swap(arr,left,parent);
            }
            parent = parent*2+1;
        }
    }
 public static void swap(int[] a,int i,int j){
        int temp = a[i];
        a[i]=a[j];
        a[j]=temp;
    }

5、歸併排序

public static void mergeSort(int[] arr){
        /*
        * 思路:先遞歸的調用sort函數把數組平均分爲兩組,然後用merge函數把分開的每個組排序併合並起來
        * */
        sort(arr,0,arr.length-1);
    }
    public static void sort(int[] arr, int begin, int end){
        if(begin>=end){
            return;
        }
        int meddle = (begin+end)/2;
        sort(arr,begin,meddle);
        sort(arr,meddle+1,end);
        merge(arr,begin,meddle,end);
    }
    public static void merge(int[] arr, int begin, int meddle, int end){
        int[] newArr = new int[end-begin+1];
        //從begin到meddle,和meddle+1到end中,把小的數放進newArr中
        int newIndex=0;
        int i=begin;
        int j = meddle+1;
        while(i<=meddle && j<=end){
            if(arr[i]>arr[j]){
                newArr[newIndex++] = arr[j++];
            }
            else{
                newArr[newIndex++] = arr[i++];
            }
        }
        while(i<=meddle){
            newArr[newIndex++] = arr[i++];
        }
        while(j<=end){
            newArr[newIndex++] = arr[j++];
        }
        //更新把排序好的newArr更新到arr對應的位置中
        for(int k = begin;k<=end;k++){
            arr[k] = newArr[k-begin];
        }
    }

6、快速排序

public static void qsort(int[] arr){
        if(arr == null || arr.length <=1 ){
            return;
        }
        partition(arr,0,arr.length-1);
    }
    public static void partition(int[] arr, int begin, int end){
        if(arr == null || begin>=end){
            return;
        }

        int small = begin-1;
        for(int index = begin; index<end;index++){
            if(arr[index]<arr[end]){
                small++;
                //System.out.println(small);
                if(index != small){
                    swap(arr,index,small);
                }
            }
        }
        small++;
        swap(arr,small,end);
        partition(arr,begin,small-1);
        partition(arr,small+1,end);
    }
    public static void swap(int[] a,int i,int j){
        int temp = a[i];
        a[i]=a[j];
        a[j]=temp;
    }

2、選擇排序

public static void selectSort(int[] arr){
        /*
        * 思路:找到數組中最小的數,把他與第一個數交換,然後忽視第一個數,繼續選出除了第一個數的最小的數,將這個最小的數與
        * 第二個數交換,以此類推
        * */
        int len = arr.length;
        for(int i =0; i<len-1;i++){
            int minIndex = i;
            for(int j = i;j<len;j++){
                if(arr[j]<arr[minIndex]){
                    minIndex = j;
                }
            }
            swap(arr,i,minIndex);
        }

    }
public static void swap(int[] a,int i,int j){
        int temp = a[i];
        a[i]=a[j];
        a[j]=temp;
    }

各個算法的時間複雜度和空間複雜度以及穩定性:


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