排序算法

选择排序算法

直接选择排序、堆排序

交换排序

冒泡排序、快速排序

插入排序

直接插入排序、折半插入排序、Shell排序

归并排序

桶式排序

基数排序


冒泡排序 O(n^2)

从第一个元素开始,比较两个相邻的元素。若相邻的元素的相对位置不正确,则交换位置;否则比较后面两个相邻的元素。

java中的排队执行 java实现各种排序算法_算法


java中的排队执行 java实现各种排序算法_java_02


八个元素最多需要七轮排序。

核心代码:

int[] bubble(int[] array){
        for(int i = 0;i < array.length - 1;i++){
            //n个元素共比较n-1轮
            for(int j = 0;j < array.length - i - 1;j++){//j和相邻元素j+1比较,length-1不然会越界
                //每轮比较剩下的元素,n个元素比较n-1次完成一轮
                if(array[j] > array[j+1]){
                    int temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                }
            }
        }
        return array;
    }

选择排序 O(n^2)

int[] select(int[] array){
        for(int i = 0;i < array.length - 1;i++){
            int min = i;
            for(int j = i + 1;j < array.length;j++){//j依次向后直到最后一个元素
                if(array[j] < array[min])
                    min = j;
            }
            int temp = array[i];
            array[i] = array[min];
            array[min] = temp;
        }
        return array;
    }

插入排序 O(n^2)

int[] insertion(int[] array){
        for(int i = 0;i < array.length - 1;i++){//控制比较的轮数和已经排好序的元素
            int j = i + 1;//已经排好序元素外的第一个元素
            while(j > 0 && array[j] < array[j-1]){//新元素一步一步往里换位置
                int temp = array[j];
                array[j] = array[j-1];
                array[j-1] = temp;
                j = j - 1;
            }
        }
        return array;
    }

归并排序 O(n*logn)

public static void mergeSort(int[] array, int low, int high){
        //将数组拆开
        int mid = (low + high) / 2;
        if(low < high){//设置递归结束条件
            //左边
            mergeSort(array, low, mid);
            //右边
            mergeSort(array, mid+1, high);
            //归并
            merge(array, low, mid, high);

            System.out.println(Arrays.toString(array));
        }
    }
    public static void merge(int[] array, int low, int mid, int high){
        //将数组依次比较合并
        int[] temp = new int[high - low + 1];//实例化一个临时数组来排序
        int i = low;
        int j = mid + 1;
        int k = 0;

        //循环 依次把较小的数先放进数组
        while(i <= mid && j <= high){
            if(array[i] < array[j])
                temp[k++] = array[i++];
            else
                temp[k++] = array[j++];
        }
        //若比较完左面还剩数组,把左面依次放进temp
        while(i <= mid){
            temp[k++] = array[i++];
        }
        //若比较完右边还剩数组,把右边依次放进temp
        while(j <= high){
            temp[k++] = array[j++];
        }
        //排好序的数组放回
        for(int n = 0; n < temp.length; n++){
            array[n + low] = temp[n];
        }
    }

快速排序 O(n*logn)

定义3个指针(high, low, pivot),要求low指向的元素小于等于pivot指向的元素;high指向的元素大于等于pivot指向的元素。

java中的排队执行 java实现各种排序算法_排序算法_03

首先,指向high的指针先向左移动(依次比较),若遇到比pivot指向的元素小的元素停下。

java中的排队执行 java实现各种排序算法_排序算法_04

将high指向的元素和low指向的元素(此时low和pivot指向同一元素)换位置。

java中的排队执行 java实现各种排序算法_排序算法_05

然后low开始向右移动(依次比较),若遇到比pivot指向的元素大的元素停下。

java中的排队执行 java实现各种排序算法_排序算法_06

将high指向的元素和low指向的元素换位置。

java中的排队执行 java实现各种排序算法_算法_07

然后,high再向左移动,找到比low指向元素小的元素停下。

java中的排队执行 java实现各种排序算法_算法_08

同理,将low指向的元素和high指向的元素换位置。

java中的排队执行 java实现各种排序算法_java_09

至此,第一轮排序结束。23(pivot元素)左边都是比它小的元素,右边都是比它大的元素。然后以pivot指向的元素为分界线,再对左右两边的小数组进行上述操作。

java中的排队执行 java实现各种排序算法_算法_10

代码实现:

public static void quickSort(int[] array, int low, int high){
        if(low < high){
            int i = low;
            int j = high;
            int pivot = array[i];

            while(i < j){//控制左右指针轮流向中间聚拢
                //右指针先向左移动,遇到比pivot小的停下
                while(i<j && array[j]>pivot)
                    j--;
                if(i < j)
                    array[i++] = array[j];//把第j个元素的值给第i个元素
                //左指针向右移动,遇到比pivot大的停下
                while(i<j && array[i]<pivot)
                    i++;
                if(i < j)
                    array[j--] = array[i];//把第i个元素的值给了第j个元素
            }
            array[i] = pivot;//把pivot的值再换给第i个元素(重复)
            quickSort(array, low, i-1);//pivot前看作一个小数组
            quickSort(array, i+1, high);//pivot后看作一个小数组
        }
    }

堆排序 O(n*logn)

public static void heapSort(int[] array){
        //构建大根堆,从最后一个不是叶子结点的节点开始
        for(int i = array.length / 2 - 1; i >= 0; i--){
            // array.length / 2 - 1 是最后一个不是叶子节点的节点,从这个节点开始遍历到根节点找最大值
            maxHeapDown(array, i, array.length - 1);
        }

        //从数组最后一个节点依次和根节点互换位置,然后排序
        for(int i = array.length - 1; i > 0; i--){
            int temp = array[i];
            array[i] = array[0];
            array[0] = temp;

            maxHeapDown(array, 0, i - 1);
        }
    }

    public static void maxHeapDown(int[] array, int start, int end){//start 当前节点起始位置 end 数组末尾
        for(int child = 2 * start + 1; child <= end; child = 2 * child + 1){//child 左孩子节点
            if(child<end && array[child]<array[child+1])
                //确保存在左右自节点,选择较大的一个
                child++;
            if(array[child] > array[start]) {
                int temp = array[child];
                array[child] = array[start];
                array[start] = temp;
            }
            else
                break;
            start = child;
        }
    }