排序算法总结

排序算法

大部分算法都是从无序区扩展到有序区

一、算法概述

1.冒泡排序 O(N2),空间O(1)

每一轮从无序区冒泡出一个最大的数到有序区

2.选择排序O(N2),空间O(1)

每一轮从无序区选择一个最大的数到有序区

3.堆排序O(NlogN),空间O(1)

其实就是选择排序的改进,每次从堆中选择一个最大值;

堆:父节点的值 >= 所有子节点的值

建堆:

在一个数组中,下标为0的元素为根节点,i的子节点为2i+1和2i+2;

从右往左、从下往上的第一个非叶子节点开始,即arr.length/2-1,与它的子节点递归比较。

建完堆后,产生一个最大值,将它与最后一个节点swap,无序区就变成了N-1,这个时候只要将根节点递归比较,就能产生次大值,依次下去...

public class HeapSort {
    public static void main(String[] args) {
        int[] array = new int[] { 2, 1, 4, 3, 6, 5, 8, 7 };
        // 接下来就是排序的主体逻辑
        sort(array);
        System.out.println(Arrays.toString(array));
    }
public static void sort(int[] array) {
    
    for (int i = array.length / 2 - 1; i >= 0; i--) {
        adjustHeap(array, i, array.length);
    }
 

    for (int j = array.length - 1; j > 0; j--) {

        adjustHeap(array, 0, j);
    }
}

public static void adjustHeap(int[] array, int i, int length) {

    int temp = array[i];

    for (int k = 2 * i + 1; k < length; k = 2 * k + 1) {

        if (k + 1 < length && array[k] < array[k + 1]) {
            k++;
        }

        if (array[k] > temp) {
            swap(array, i, k);
            
            i = k;

        } else {
            break;
        }
    }
}

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

4.插入排序O(N2),空间O(1)

在数组大多数元素有序时有优势

从第2个元素开始,与前面的元素比较,若小于前面的,则swap,注意要向前比较一直到不用swap。

5.希尔排序O(?),空间O(1)

假定一个数k,如果说插入排序每次是与前面间隔1步的比较,那么希尔排序就是与前面间隔k步的比较

k每轮减1,一直到1,这样做其实利用插入排序的优势。

6.归并排序O(NlogN),空间O(N)

分治,O(N)合并

7.快速排序O(NlogN),空间O(logN)

主要难写的就是划分区域的部分

划分为左区域、右区域,先从右边扫,再从左边扫

(各扫到一个不满足条件的数后,交换,进行下一轮)

   temp = a[left]; //temp中存的就是基准数
    i = left;
    j = right;
    while(i != j) { //顺序很重要,要先从右边开始找
     while(a[j] > temp && i < j)
         j--;
     while(a[i] <= temp && i < j)//再找左边的
         i++;       
     if(i < j)//交换两个数在数组中的位置
     {
         t = a[i];
         a[i] = a[j];
         a[j] = t;
     }
    }
    //最终将基准数归位
    a[left] = a[i];
    a[i] = temp;

为啥这个做法是正确的?

分情况讨论一下即可:

两边若都扫到一个不满足a[j] > temp/<= temp 条件的,则交换;

右边是一定会扫到,而左边没扫到,则可以停止了,最终将基准数归位。

8.桶排序O(N),空间O(M)

桶即hash的那个桶

  • 计数排序

    数字区间范围小的,比如年龄、身高

  • 基数排序

    以数字为0-9作为桶,从低位到高位排

posted @ 2019-07-14 12:27 hzhuan 阅读(...) 评论(...) 编辑 收藏