LeetCode前置課-2-八大排序算法

1、冒泡

//,冒泡
    public static void sortMaopao(){
        int[] arr = {3,9,-1,10,20,1};
        System.out.println("排序前:"+ Arrays.toString(arr));
        int temp;
        for(int j=0 ;j<arr.length-1; j++){
            for(int i=0 ; i<arr.length-1; i++){
                if(arr[i]>arr[i+1]){
                    temp=arr[i];
                    arr[i]=arr[i+1];
                    arr[i+1]=temp;
                }
            }
        }
        System.out.println("排序後:"+ Arrays.toString(arr));
    }

2、選擇排序

//選擇排序
    public static  void selectSort(){
        int[] arr = {3,9,-1,10,20,1};
        System.out.println("排序前:"+ Arrays.toString(arr));

        for(int i=0; i<arr.length-1; i++){
            int min = arr[i];//假設爲最小數
            int minIndex = i;
            for(int j=i+1 ;j<arr.length;j++){//i+1
                if(min>arr[j]){
                    min=arr[j];//最小數
                    minIndex=j;//最小數的下標
                }
            }
            if(minIndex!=i){
                arr[minIndex]=arr[i];
                arr[i]=min;
            }
        }
        System.out.println("排序前:"+ Arrays.toString(arr));
    }

3、插入排序

//插入排序
    public static  void insertSort(){
        int[] arr = {3,9,-1,10,20,1};
        System.out.println("排序前:"+ Arrays.toString(arr));
        int insertVal;
        int insertIndex;
        for(int i=1 ; i<arr.length; i++){
            insertVal=arr[i];
            insertIndex=i-1;
            //insertIndex>=0保障不越界,等於-1表示找到了最前邊,
            //跳出while;insertVal<arr[insertIndex]說明還沒有找到合適的位置
            while(insertIndex>=0 && insertVal<arr[insertIndex]){
                arr[insertIndex+1]=arr[insertIndex];
                insertIndex--;
            }
            if(insertIndex+1!=i){
                arr[insertIndex+1]=insertVal;
            }
        }
        System.out.println("排序後:"+ Arrays.toString(arr));
    }

4、希爾排序

//希爾排序(一種插入排序,簡單增量排序)
    public static void shellSort(){
        int[] arr = {3,9,-1,10,20,1,7,2,0};
        System.out.println("排序前:"+ Arrays.toString(arr));
        int size = arr.length;
        for(int gap =size/2 ; gap>0; gap = gap/2){
            for(int i=gap;i<arr.length;i++){//根據gap可以分爲多段,比較每一段
                int j= i;
                int temp=arr[j];//暫存第一個要比較的數
                while (j-gap>=0 && temp<arr[j-gap]){//因爲每個分組可能有多個值,要依次比較並判斷進行交換
                    arr[j]=arr[j-gap];
                    j=j-gap;
                }
                arr[j]=temp;
            }
        }
        System.out.println("排序後:"+ Arrays.toString(arr));
    }

5、快速排序

 //快速排序(遞歸方式)
    public static  void quictSort(int[] arr,int left ,int right){
        int l = left;
        int r = right;
        int pivot = arr[(left+right)/2];
        int temp =0;
        while (l<r){
            while (arr[l]<pivot){//在pivot左邊一直找,找到大於pivot的值才退出
                l=l+1;
            }
            while (arr[r]>pivot){
                r=r-1;
            }
            if(l>=r){//說明已經按照左小右大的順序排列了
                break;
            }
            temp=arr[l];//找到了,進行冒泡交換排序
            arr[l]=arr[r];
            arr[r]=temp;
        }
        if(l==r){//如果l==r,必須l++,r--否則棧溢出
            l=l+1;
            r=r-1;
        }
        if(left<r){
            quictSort(arr,left,r);
        }
        if(right>l){
            quictSort(arr,l,right);
        }
    }

6、歸併排序

//歸併排序(又叫分治排序)
    public static void mergeSort(int arr[] ,int left, int right , int[] temp){
        if(left<right){
            //分
            int mind = (right+left)/2;
            mergeSort(arr, left, mind, temp);
            mergeSort(arr, mind+1, right, temp);
            //合
            merge(arr, left,mind, right, temp);
        }
    }

 private static void merge(int[] arr, int left, int mind, int right, int[] temp) {
        int i =left;//左邊有序序列的初始化索引
        int j = mind+1;//右邊有序序列的初始索引
        int t =0;//temp數組當前索引
        //1、左右兩個有序序列考進temp
        while (i<=mind && j<=right){
            if(arr[i]<arr[j]){
                temp[t]=arr[i];
                i++;
                t++;
            }else {
                temp[t]=arr[j];
                j++;
                t++;
            }
        }
        //2、左右兩個有一個走完了,則把另一個拷進temp
        while (i<=mind){
            temp[t]=arr[i];
            i++;
            t++;
        }
        while (j<=right){
            temp[t]=arr[j];
            j++;
            t++;
        }
        //3將temp數組的元素拷貝到array,注意並不是每次都拷貝所有,
        // 如果有八個,第一次tempLeft=0,right=1;
        //tempLeft=2,right=3;tempLeft0,right3,最後一次tempLeft=0,right=7
        t=0;
        int tempLeft = left;
        while (tempLeft<=right){
            arr[tempLeft]=temp[t];
            t++;
            tempLeft++;
        }
    }

7、基數排序

//基數排序(對桶排序的優化)
    public  static void radixSort(int[] array){
        int max = array[0];//找出最大數
        for(int i=0; i<array.length;i++){
            if(max<array[i]){
                max= array[i];
            }
        }
        int maxLength = (max+"").length();//計算最大數的長度位數
        int bucket[][] = new int[10][array.length];//聲明10個桶
        int bucketCount[] = new int[10];//表示每個桶中存放多少個數
        for(int i=0,n=1;i<maxLength;i++,n=n*10){//每一位進行放桶和放回操作
            //放入桶
            for(int j=0;j<array.length;j++){
                int num = array[j]/n%10;//取當前循環位數的數字
                bucket[num][bucketCount[num]]=array[j];
                bucketCount[num]=bucketCount[num]+1;
            }
            //放回數組
            int index =0;
            for(int k=0;k<bucketCount.length;k++){
                if(bucketCount[k]>0){//表示查出有數的桶
                    for(int L =0;L<bucketCount[k];L++){
                        array[index] = bucket[k][L];
                        index++;
                    }
                }
                bucketCount[k]=0;//將拷貝完的重新記爲0
            }
        }
    }

8、堆排序,堆排序依賴樹

移步查看樹部分文章

排序總結:

 

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