常见排序算法

201 阅读4分钟

1 冒泡排序

package sort;

/*
冒泡排序:时间复杂度O(N^2)
 */
 
        public class BubbleSort {
            public static void main(String[] args) {
                int [] a = {1,5,2,7,4,9};
                bubbleSort(a);
                for(int i = 0; i < a.length; i++){
                System.out.println(a[i]);
            }
        }
    
         public static void bubbleSort(int [] arr){
                if(arr == null || arr.length <2){
                 return ;
                 }

        for (int end = arr.length - 1; end > 0; end--){
            for(int i = 0; i< end ;i++){
                if (arr[i] > arr[i+1]){
                    swap(arr,i,i+1);
                }
            }
        }
    }

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

2 选择排序

package sort;

/*
选择排序:时间复杂度O(N^2)
*/

        public class SelectSort {
            public static void main(String[] args) {
                int [] a = {1,5,2,7,4,9,10,8};
                selectSort(a);
                for(int i = 0; i < a.length; i++){
                System.out.println(a[i]);
            }
        }

        public static void selectSort(int [] arr){
            if(arr == null || arr.length <2){
                return ;
            }
            for(int i = 0;i < arr.length-1; i ++){
                //minIndex:最小的数字的下标
                int minIndex = i;
                for (int j = i+1; j <arr.length;j++){
                    minIndex = arr[j] < arr[minIndex] ? j : minIndex;
                }
                swap(arr,i,minIndex);
            }
        }


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

3 插入排序

package sort;

/*
    插入排序的时间复杂度和数据状况有关,最好情况是O(N),最坏情况是O(N^2)
 */
 
    public class InsertSort {
        public static void main(String[] args) {
        int [] a = {1,5,2,7,4,9,89,10,8};
        insertSort(a);
        for(int i = 0; i < a.length; i++){
            System.out.println(a[i]);
        }
    }

    public static void insertSort(int [] arr){
        if(arr == null || arr.length < 2){
            return ;
        }
        for (int i = 1; i <arr.length ; i++){
            for (int j = i-1; j>= 0 && arr[j] > arr[j+1]; j--){
                swap(arr,j,j+1);
            }
        }
    }

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

4 归并排序

package sort;

/*
    时间复杂度O(N*logN)  额外空间复杂度O(N)
 */

    public class MergeSort {
        public static void mergeSort(int[] arr){
        if(arr == null || arr.length < 2){
            return ;
        }

        sortProcess(arr,0,arr.length-1);
    }

    public static void sortProcess(int[] arr,int L,int R){
        if(L == R){
            return ;
        }
        int mid = L + ((R-L)>>1);
        sortProcess(arr,L,mid);
        sortProcess(arr,mid+1,R);
        merge(arr,L,mid,R);
    }

    public static void merge(int [] arr,int L,int mid,int R){
        int [] help = new int [R-L+1];
        int i = 0;
        int p1 = L;
        int p2 = mid + 1;
        while(p1 <= mid && p2 <= R){
            help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
        }
        //两个必有且只有一个越界
        while(p1 <= mid){
            help[i++] = arr[p1++];
        }
        while(p2 <= R){
            help[i++] = arr[p2++];
        }
        //将merge后的数组拷贝回到原数组
        for(i=0;i<help.length;i++){
            arr[L+i] = help[i];
        }
    }

    public static void main(String[] args) {
        int [] a = {1,5,2,7,4,9,89,10,8};
        mergeSort(a);
        for(int i = 0; i < a.length; i++){
            System.out.println(a[i]);
        }
    }}

5 对数器的使用

package sort;
import java.math.*;
import java.util.Arrays;

public class DuiShuQi {
public static void insertSort(int [] arr){
    if(arr==null||arr.length<2){
        return;
    }
    for(var i=1;i<arr.length;i++){
        for(var j=i-1;j>=0&&arr[j]>arr[j+1];j--){
            swap(arr,j,j+1);
        }
    }
}

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

//for test
//size:数组的最大长度    value:数组中的每个值
public static int[] generateRandomArray(int size,int value){
    int [] arr = new int[(int)((size+1)*Math.random())];
    for(int i = 0;i<arr.length;i++){
        arr[i]=(int)((value+1)*Math.random()-(int)(value*Math.random()));
    }
    return arr;
}

//for test 绝对正确的方法
public static void rightMethod(int [] arr){
    Arrays.sort(arr);
}

public static int[] copyArray(int [] arr){
    if(arr == null){
        return null;
    }
    int [] res = new int [arr.length];
    for (int i = 0; i < arr.length; i++) {
        res[i] = arr[i];
    }
    return res;
}

//for test
public static boolean isEqual(int[] arr1,int[] arr2){
    if ((arr1==null && arr2 != null)||(arr1 != null && arr2 == null)){
        return false;
    }
    if (arr1 == null && arr2 == null){
        return true;
    }
    if (arr1.length != arr2.length){
        return  false;
    }
    for(int i = 0; i < arr1.length ; i++){
        if (arr1[i] != arr2[i]){
            return false;
        }
    }
    return true;
}

//for test
public static void printArray(int [] arr){
    for (int i : arr) {
        System.out.print(" " + i);
    }
}

//for test
public static void main(String[] args) {
    int testTime = 500000;
    int size = 100;
    int value = 100;
    boolean succeed = true;
    for(int i = 0; i < testTime;i++){
        int [] arr1 = generateRandomArray(size,value);
        int [] arr2 = copyArray(arr1);
        int [] arr3 = copyArray(arr1);
        insertSort(arr1);
        rightMethod(arr2);
        if(!isEqual(arr1,arr2)){
            succeed = false;
            printArray(arr3);
            break;
        }
    }
    System.out.println(succeed ? "Nice!" : "Fucking fucked!");

    int [] arr = generateRandomArray(size,value);
    printArray(arr);
    insertSort(arr);
    printArray(arr);
}}

6 获得最大值

package sort;

/*
master公式的使用
T[N] = aT[N/b] + f (N)(直接记为T[N] = aT[N/b] + O(N^d))

其中 a>=1 and b>1 是常量,其表示的意义是N表示问题的规模,a表示递归的次数也就是生成的子问题数,b表示每次递归是原来的1/b之一个规模,
f(N)表示分解和合并所要花费的时间之和。

解法:
①当d<log(b,a)时,时间复杂度为O(N^(log(b,a)))
②当d=log(b,a)时,时间复杂度为O((N^d)*logN)
③当d>log(b,a)时,时间复杂度为O(N^d)
 */

    public class GetMax {
        public static int getMax(int [] arr,int L,int R){
            if(L == R){
                return arr[L];
            }
            int mid = (L+R)/2;
            int maxLeft = getMax(arr,L,mid);
            int maxRight = getMax(arr,mid+1,R);
            return Math.max(maxLeft,maxRight);
        }

    public static void main(String[] args) {
        int [] arr = {4,3,2,1};
        System.out.println(getMax(arr,0,arr.length-1));
    }}

7 小和问题

package sort;

/*
    小和问题
 */

    public class SmallSum {
        public static void main(String[] args) {
            int a [] = {1,2,4,6,8};
            System.out.println(smallSum(a));
        }
        public static int smallSum ( int[] arr){
            if (arr == null || arr.length < 2) {
                return 0;
            }
        return mergeSort(arr, 0, arr.length - 1);
    }

    public static int mergeSort ( int[] arr, int l, int r){
        if (l == r) {
            return 0;
        }
        //防止溢出,位运算的速度也要比算术运算快一些
        int mid = l + ((r - l) >> 1);
        return mergeSort(arr, l, mid)
                + mergeSort(arr, mid + 1, r)
                + merge(arr, l, mid, r);
    }

    public static int merge ( int[] arr, int l, int m, int r){
        int[] help = new int[r - l + 1];
        int i = 0;
        int p1 = l;
        int p2 = m + 1;
        int res = 0;
        while (p1 <= m && p2 <= r) {
            res += arr[p1] < arr[p2] ? (r - p2 + 1) * arr[p1] : 0;
            help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
        }
        //两个必有且只有一个越界
        while (p1 <= m) {
            help[i++] = arr[p1++];
        }
        while (p2 <= r) {
            help[i++] = arr[p2++];
        }
        //将merge后的数组拷贝回到原数组
        for (i = 0; i < help.length; i++) {
            arr[l + i] = help[i];
        }
        return res;
    }}