算法-排序

0、复杂度及稳定性

排序算法平均时间复杂度最差时间复杂度最好时间复杂度空间复杂度

稳定性(相等元素相对顺序不变)

冒泡排序O(n^2)O(n^2)

O(n)有序

O(1)稳定
插入排序O(n^2)O(n^2)

O(n)有序

O(1)稳定
选择排序O(n^2)O(n^2)O(n^2)O(1)不稳定
希尔排序O(nlogn) O(n^2)O(nlogn)O(1)不稳定
快速排序O(nlogn)O(n^2)逆序

O(nlogn)

O(logn)不稳定
归并排序O(nlogn)O(nlogn)O(nlogn)O(n)稳定
堆排序O(nlogn)O(nlogn)O(nlogn)O(1)不稳定
桶排序O(k + n)O(n^2)

O(n)

O(n+k)

稳定
计数排序O(n+k)O(n+k)O(n+k)

O(k)

稳定
基数排序O(n×k)O(n×k)O(n×k)O(n×k)稳定

一、冒泡排序

比较相邻的元素,若顺序错误则交换

public void bubbleSort(int[] array) {
    for (int i = 0; i < arr.length - 1; i++) {  
        for (int j = 0; j < arr.length - i - 1; j++) {  
            if (array[j] > array[j+1]) {  
                swap(j, j+1, array)
            }  
        }  
    }  
}  

二、选择排序

在未排序序列中找到最小元素,存放到排序序列的起始位置。再从剩余未排序元素中继续寻找最小元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

public void selectionSort(int[] array) {  
    for (int i = 0; i < array.length - 1; i++) {  
        // 找到最小元素的索引  
        int minIndex = i;  
        for (int j = i + 1; j < array.length; j++) {  
            if (array[j] < array[minIndex]) {  
                minIndex = j;  
            }  
        }  
        swap(i, minIndex, array);
    }  
}  

三、插入排序

将一个待排序的元素插入到已排序的序列中的适当位置(从后向前扫描),直到全部插入完

public void insertionSort(int[] array) {  
    int n = array.length;  
    for (int i = 1; i < n; ++i) {  
        int pre = i - 1;  
        while (pre >= 0 && array[pre] > array[i]) {  
            array[pre + 1] = array[pre];  
            pre = pre - 1;  
        }  
        array[pre + 1] = array[i];  
    }  
}  

四、希尔排序

插入排序的一种更高效的改进版

public void shellSort(int[] array) {  
    int n = array.length;  
    int gap = n / 2;  
    // Start with a big gap, then reduce the gap  
    while (gap > 0) {
        for (i = gap; i < n; i++) {  
            int pre = i - gap;
            while (pre >= 0 && array[pre] > array[i]) {
                array[pre + gap] = array[pre];
                pre -= gap; 
            }
            array[pre + gap] = array[i];  
        }      
        gap /= 2;
    }   
}  

五、快速排序

采用分治法。选择一个“基准”元素,通过一趟排序将待排序的数据分割成独立的两部分,其中一部分的所有数据都比基准元素小,另一部分的所有数据都比基准元素大。以此类推,达到有序

详解:https://segmentfault.com/a/1190000040022056#item-2-1

class Solution {
    public int[] sortArray(int[] nums) {
        //快排
        sort(0, nums.length, nums);
        return nums;
    }
    public void sort(int start, int end, int[] nums) {
        if (start >= end) {
            return;
        }
        int partition = partition(start, end, nums);
        sort(start, partition, nums);
        sort(partition + 1, end, nums);
    }

    public int partition(int start, int end, int[] nums) {
        int point = start;
        int piovt = nums[end - 1];
        for (int i = start; i < end - 1 ; i++) {
            if (nums[i] <= piovt) {
                swap(i, point, nums);
                point++;
            }
        }
        swap(point, end - 1, nums);
        return point;
    }
    public void swap(int i, int j, int[] nums) {
        if (i == j) {return;}
        nums[i] ^= nums[j];
        nums[j] ^= nums[i];
        nums[i] ^= nums[j];
    }
}

六、归并排序

先递归分解数组,再将已有序的子序列合并,得到完全有序的序列

 public void mergeSort(int[] array, int left, int right) {  
    if (left < right) {  
        // 找到中间位置  
        int mid = (left + right) / 2;  
        // 对左半部分进行归并排序  
        mergeSort(array, left, mid);  
        // 对右半部分进行归并排序  
        mergeSort(array, mid, right);  
        // 合并左右两部分  
        merge(array, left, mid, right);  
    }  
}  

public void merge(int[] array, int left, int mid, int right) {  
    // 创建一个临时数组来辅助归并操作  
    int[] temp = new int[right - left];  
    // 左指针和右指针分别指向左半部分和右半部分的起始位置  
    int i = left;  
    int j = mid;  
    int k = 0;  
    // 合并两个有序数组到临时数组  
    while (i < mid && j < right) {  
        if (array[i] <= array[j]) {  
            temp[k++] = array[i++];  
        } else {  
            temp[k++] = array[j++];  
        }  
    }  
    // 将左半部分剩余的元素复制到临时数组  
    while (i < mid) {  
         temp[k++] = array[i++];  
    }  
    // 将右半部分剩余的元素复制到临时数组  
    while (j < right) {  
        temp[k++] = array[j++];  
    }  
    // 将临时数组中的元素复制回原数组  
    for (k = 0; k < temp.length; k++) {  
        array[left + k] = temp[k];  
    }  
}  

七、堆排序

利用堆进行排序-见数据结构+算法-优快云博客

八、桶排序

九、计数排序

十、基数排序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值