Java SE七大排序—堆排序,快速排序,归并排序(下)

堆排序:

思路:基本原理也是选择排序,只是不在使用遍历的方式查找无序区间的最大的数,而是通过堆来选择无序区间的最大的数。 //不稳定
注意: 排升序要建大堆;排降序要建小堆。
★建大堆的时候,每次是将最后一个元素放在最上面,然后向下调整,将最大的调整到堆顶,然后将堆顶元素归栈,依次循环直到堆里只剩下一个元素。

import java.util.Arrays;
public class HeapSort {
    private static void swap(int[] array, int i, int j) {
        int t = array[i];
        array[i] = array[j];
        array[j] = t;
    }
    public static void heapSort(int[] array) {
        createHeapBig(array);
        for (int i = 0; i < array.length - 1; i++) {
            // 无序 [0, array.length - i)
            // 交换 array[0], array[length - i - 1]
            // 无序 [0, array.length - i - 1)
            // 无序长度 array.length - i - 1
            // 下标 0 进行向下调整
            swap(array, 0, array.length - i - 1);
            shiftDownBig(array, 0, array.length - i - 1);
        }
    }
    private static void createHeapBig(int[] array) {    //建大堆
        for (int i = (array.length - 2) / 2; i >= 0; i--) {
            shiftDownBig(array, i, array.length);
        }
    }
    private static void shiftDownBig(int[] array, int i, int size) {      //向下调整
        while (2 * i + 1 < size) {
            int max = 2 * i + 1;
            if (max + 1 < size && array[max+1] > array[max]) {
                max = max + 1;
            }
            if (array[i] >= array[max]) {
                return;
            }
            swap(array, i, max);
            i = max;
        }
    }
    public static void main(String[] args){
        int[] array={4,5,0,9,6,5,3,1,2,9,3};
        heapSort(array);
        System.out.println(Arrays.toString(array));   //以数组的形式输出
    }
}

快速排序:(partition部分有三种方法)

思路:1. 从待排序区间选择一个数,作为基准值(pivot);
2. Partition: 遍历整个待排序区间,将比基准值小的(可以包含相等的)放到基准值的左边,将比基准值大的(可以包含相等的)放到基准值的右边;
3. 采用分治思想,对左右两个小区间按照同样的方式处理,直到小区间的长度 == 1,代表已经有序,或者小区间的长度 == 0,代表没有数据 //不稳定

import java.util.Arrays;
public class Test0926 {
    public static void swap(int[] array,int i,int j){
        int t=array[i];
        array[i]=array[j];
        array[j]=t;
    }
    public static void quickSort(int[] array,int left,int right){   //left,right指的是下标

        quickSortInternal(array,0,array.length-1);
    }
    private static void quickSortInternal(int[] array,int left,int right){
        if(left==right){
            return;
        }
        if(left>right){
            return;
        }
        int pivotIndex=partition(array,left,right);
        quickSortInternal(array,left,pivotIndex-1);
        quickSortInternal(array,pivotIndex+1,right);
    }
    private static int partition(int[] array,int left,int right){
        int i=left;
        int j=right;
        int pivot=array[left];
        while(i<j){
            while(i<j&&array[j]>=pivot){
                j--;
            }
            while(i<j&&array[i]<=pivot){
                i++;
            }
            swap(array,i,j);
        }
        swap(array,i,left);
        return i;
    }


    //挖坑法
    private static int partition1(int[] array,int left,int right){
        int i=left;
        int j=right;
        int pivot=array[left];
        while(i<j){
            while(i<j&&array[j]>=pivot){
                j--;
            }
            array[i]=array[j];
            while(i<j&&array[i]<=pivot){
                i++;
            }
            array[j]=array[i];
        }
        array[i]=pivot;
        return i;
    }



    private static int partition2(int[] array,int left,int right){
        int d=left+1;
        int pivot=array[left];
        for(int i=left+1;i<=right;i++){
            if(array[i]<pivot){
                swap(array,i,d);
                d++;
            }
        }
        swap(array,d-1,left);
        return d-1;
    }
    public static void main(String[] args){
        int[] array={4,5,0,9,6,5,3,1,2,9,3};
        quickSort(array,0,9);
        System.out.println(Arrays.toString(array));  //以数组的形式输出
    }
}

归并排序:

思路:将一个数组分为两部分,对组内的数进行拆分排序,再合并,直到组内的数都排好序为止,采用的是分治的思想。//稳定

import java.util.Arrays;
public class Test0928 {
    public static void mergeSort(int[] array){
        mergeSortInternal(array,0,array.length);
    }
    private static void mergeSortInternal(int[] array,int low,int high){
        if(low>=high-1){        //考虑是否溢出
            return;
        }
        int mid=(low+high)/2;
        mergeSortInternal(array,low,mid);
        mergeSortInternal(array,mid,high);

        merge(array,low,mid,high);
    }
    private static void merge(int[] array,int low,int mid,int high){
        int i=low;
        int j=mid;
        int length=high-low;
        int[] extra=new int[length];     //定义一个新数组
        int k=0;                         //新建数组的下标
        while(i<mid&&j<high){              //此时,将数组从mid处分为两个区间,下标分别为i,j
            if(array[i]<=array[j]) {       //如果前者的元素小于后者,则将前者的元素搬到新数组
                extra[k++] = array[i++];    //后置++,先引用再自增
            }else{                          //后者元素大于前者
                extra[k++]=array[j++];
            }
        }
        while(i<mid){                    //这是后面的数组已为空的情况下,直接将前面的数组剩下的元素全部搬到新数组
            extra[k++]=array[i++];
        }
        while(j<high){                    //这是前面的数组已为空的情况
            extra[k++]=array[j++];
        }
        for(int t=0;t<length;t++){         //再将新数组的元素搬到原来的数组
            array[low+t]=extra[t];
        }
    }
    public static void main(String[] args){
        int[] array={4,5,0,9,6,5,3,1,2,9,3};
        mergeSort1(array);
        System.out.println(Arrays.toString(array));      //按数组的方式打印
    }

}

运行结果:
在这里插入图片描述

发布了61 篇原创文章 · 获赞 3 · 访问量 1226

猜你喜欢

转载自blog.csdn.net/qq_44847147/article/details/101620874
今日推荐