『Java』排序算法整合

直接插入排序

直接插入排序(Straight Insertion Sort)的基本思想是:把n个待排序的元素看成为一个有序表和一个无序表。开始时有序表中只包含1个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,将它插入到有序表中的适当位置,使之成为新的有序表,重复n-1次可完成排序过程。
在这里插入图片描述

    public static void insertSort(int[] array){
        int bound = 1;
        for ( ; bound < array.length; bound++){
            int tmp = array[bound];
            int cur = bound - 1;
            for( ; cur >= 0; cur--){
                if(array[cur] > tmp){
                    array[cur + 1] = array[cur];
                }else{
                    break;
                }
            }
            array[cur + 1] = tmp;
        }
    }
空间复杂度:O(1)
时间复杂度:最好O(n)平均 O(n²)最坏O(n²)
稳定性:稳定

插入排序,初始数据越接近有序,时间效率越高。如果当前序列很短,插入排序效率也很高。

希尔排序

把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的元素越来越多,当增量减至1时,整个区间恰被分成一组,算法便终止。
希尔排序是对直接插入排序的优化。当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。
在这里插入图片描述

public static void shellSort(int []array) {
        int gap = array.length;
        while (gap > 1) {
            gap /= 2;
        }
        insertSortGap(array,gap);
    }
    public static void insertSortGap(int[] array,int gap){
        int bound = 1;
        for(; bound < array.length; bound++){
            int tmp = array[bound];
            int cur = bound - gap;
            for(; cur >=0; cur--){
                if(array[cur] > tmp){
                    array[cur + gap] = array[cur];
                }else{
                    break;
                }
            }
            array[cur+gap] = tmp;
        }
    }
空间复杂度:O(1)
时间复杂度:最好O(n)平均 O(n^1.3)最坏O(n²)
稳定性:不稳定

直接选择排序

每一次从无序区间选出最大(或最小)的一个元素,存放在无序区间的最后(或最前) ,直到全部待排序的数据元素排完 。
在这里插入图片描述

public static void selectSort(int[]array){
        for(int bound = 0; bound < array.length; bound++){
            for(int cur = bound + 1; cur < array.length; cur++){
                int tmp = array[bound];
                if(array[cur] < tmp){
                    array[bound] = array[cur];
                    array[cur] = tmp;
                }
            }
        }
    }

空间复杂度:O(1)
时间复杂度:O(n)
稳定性:不稳定

堆排序

首先用给定得元素建立堆(①完全二叉树②父节点值>子节点值),堆建立成功,交换第一个和最后一个元素,然后这个最后一个元素就算排序成功了。
在这里插入图片描述

public static void heapSort(int[] array){
        creatHeap(array);
        for(int i = 0; i < array.length; i++){
            swap(array, array.length - i-1, 0);
            shiftDown(array,array.length -1 -i, 0);
        }
    }
    public static void creatHeap (int[] array){
        for(int i = (array.length-1-1)/2 ; i>=0; i--){
            shiftDown(array, array.length, i);
        }
    }
    public static void shiftDown(int[] array, int size, int index){
        int parent = index;
        int child = 2 * parent + 1;
        while(child < size){
            if(child + 1 < size && array[child + 1] > array[child]){
                child = child + 1;
            }
            if(array[parent] < array[child]){
                swap(array, child, parent);
            }else{
                break;
            }
            parent = child;
            child = 2 * parent +1;
        }
    }
    public static void swap(int[] array, int x, int y){
        int tmp = array[x];
         array[x] = array[y];
         array[y] = tmp;
    }
空间复杂度:O(1)
时间复杂度:O(n * log(n))
稳定性:不稳定

冒泡排序

在无序区间,通过相邻数的比较,将最大的数冒泡到无序区间的最后,持续这个过程,直到数组整体有序
在这里插入图片描述

    public static void bubbleSort(int[] arr){
        for(int i = 0; i < arr.length; i++){
            for(int j = i +1 ; j < arr.length; j++){
                if(arr[i] > arr[j]){
                    swap(arr, i, j);
                }
            }
        }
    }
    public static void swap(int[] array, int x, int y){
        int tmp = array[x];
         array[x] = array[y];
         array[y] = tmp;
    }
空间复杂度:O(1)
时间复杂度:最好O(n)平均 O(n²)最坏O(n²)
稳定性:稳定

快速排序

选择一个基准数,通过一趟排序将要区间分成两部分。其中一部分的所有数据都比另外一部分小。然后,在按此方法对这两部分数据进行快排,整个排序过程可以递归进行。
在这里插入图片描述

 public static void quickSort(int[] array, int left, int right ){
        if(left < right){
            int i = left;
            int j = right;
            int baseValue = array[i];
            while ( i < j){
                while( i < j && array[j] > baseValue){
                    j--; // 从右向左找第一个小于baseValue的值
                }
                if(i<j){
                    array[i++] = array[j];
                }
                while (i < j && array[i] < baseValue){
                    i++;
                }
                if(i<j){
                    array[j--]=array[i];
                }
            }
            array[i] = baseValue;
            quickSort(array,left,i-1);
            quickSort(array,i+1,right);
        }
    }
空间复杂度:最好O(log(n))平均O(log(n))最坏O(n)
时间复杂度:最好O(n * log(n))平均O(n * log(n))最坏O(n^2)
稳定性:不稳定

归并排序

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子 序列段间有序。
在这里插入图片描述
使用递归

public class Sort {
    public static void mergeSort(int[] array) {
        mergeSortHelper(array, 0, array.length);
    }

    private static void mergeSortHelper(int[] array, int left, int right) {
        if (left >= right || right - left == 1) {
            return;
        }

        int mid = (left + right) / 2;

        mergeSortHelper(array, left, mid);
        mergeSortHelper(array, mid, right);
        merge(array, left, mid, right);
    }

    private static void merge(int[] array, int left, int mid, int right) {
        int length = right - left;
        int[] temp = new int[length];
        int tempIndex = 0;
        int i = left;
        int j = mid;
        while (i < mid && j < right) {
        	//加入 = 使得数据稳定
            if (array[i] <= array[j]) {
                temp[tempIndex++] = array[i++];
            }else {
                temp[tempIndex++] = array[j++];
            }
        }
        while (i < mid) {
            temp[tempIndex++] = array[i++];
        }
        while (j < right) {
            temp[tempIndex++] = array[j++];
        }

        for (int k = 0; k < length; k++) {
            array[left + k] = temp[k];
        }
    }
    public static void main(String[] args) {
        int[] arr = {9, 5, 2, 7, 3, 6, 1, 8};
        mergeSort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

不使用递归

public static void mergrSortByLoop(int[] array) {
    for (int i = 1; i < array.length; i = i * 2) {
        for (int j = 0; j < array.length; j = j+ 2 * i) {
            int low = j;
            int mid = j + i;
            if (mid >= array.length) {
                continue;
            }
            int high = mid + 1;
            if (high > array.length) {
               high = array.length;
            }
            merge(array, low, mid, high);
        }
    }
}
空间复杂度:O(n)
时间复杂度:O(n * log(n))
稳定性:稳定
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值