数组排序

大纲:

  1. 冒泡排序
  2. 选择排序
  3. 插入排序
  4. 希尔排序
  5. 快速排序
  6. 归并排序
  7. 基数排序
  8. 堆排序

 

一、冒泡排序

  /**
     * 冒泡排序
     * 依次比较相邻的两个值,将大的交换到这2个位置的后面一个位置,然后继续比较直到最后一个值则找出了最大的数。
     *
     * @param arr
     */
    private static void bubble(int[] arr) {
        for (int i = 0; i <= arr.length - 1; i++) {
            for (int j = 0; j <= arr.length - 2 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

 

二、选择排序

  /**
     * 选择排序
     * 遍历数组长度n个元素找到最大的,放到最后,再便利数组长度n-1个元素最大的,放到倒数第二个位置。
     *
     * @param arr
     */
    private static void selection(int[] arr) {
        int maxindex = 0;
        for (int i = 0; i <= arr.length - 1; i++) {
            for (int j = 0; j <= arr.length - 1 - i; j++) {
                if (arr[j] > arr[maxindex]) {
                    maxindex = j;
                }
            }
            int temp = arr[arr.length - 1 - i];
            arr[arr.length - 1 - i] = arr[maxindex];
            arr[maxindex] = temp;
        }
    }

 

三、插入排序

  /**
     * 插入排序
     * 依次左侧n个数组有序,每次找到n+1因该插入的位置
     *
     * @param arr
     */
    private static void insertion(int[] arr) {
        for (int i = 1; i <= arr.length - 1; i++) {
            int temp = arr[i];
            int index = i;
            while (index - 1 >= 0 && temp < arr[index - 1]) {
                arr[index] = arr[index - 1];
                index--;
            }
            arr[index] = temp;
        }
    }

 

四、希尔排序

  /**
     * 希尔排序
     * 步长分别是arr.length开始,每次除以2
     * 然后将arr分成gap个与步长相同的组,分别进行插入排序
     *
     * @param arr
     */
    private static void shell(int[] arr) {
        for (int gap = arr.length/2; gap >0; gap/=2) {
            for (int i = gap; i < arr.length; i++) {
                int temp = arr[i];
                int index = i;
                while (index - gap >= 0 && arr[index - gap] > temp) {
                    arr[index] = arr[index-gap];
                    index-=gap;
                }
                arr[index] = temp;
            }
        }
    }

 

五、快速排序

  /**
     * 快速排序
     * 将第一个数作为中轴,将比它大的放在它右边,比它小的都放在它左边
     * 再递归两边的子数组
     *
     * @param arr
     */
    private static void qs(int[] arr) {
        quickSort(arr, 0, arr.length - 1);
    }

    private static void quickSort(int[] arr, int begin, int end) {
        if (end>begin) {
            int left = begin;
            int right = end;
            int temp = arr[left];
            while (right > left) {
                while (right > left && arr[right] >= temp) {
                    right--;
                }
                arr[left] = arr[right];
                while (right > left && arr[left] <= temp) {
                    left++;
                }
                arr[right] = arr[left];
            }
            arr[right] = temp;
            quickSort(arr,begin,right-1);
            quickSort(arr,right+1,end);
        }
    }

 

六、归并排序

    /**
     * 归并排序
     * 分治思想,先将数组拆分至2个数,然后合并计算
     * 合并过程:分成左右段用双指针,将小的一个放到临时数组中,再将左右没有放置到临时数组中的copy过去,最后复制回arr中
     * @param arr
     */
    private static void ms(int arr[]) {
        int[] temp = new int[arr.length];
        mergeSort(arr,0,arr.length-1,temp);
    }

    private static void mergeSort(int[] arr, int begin, int end, int[] temp) {
        if (end>begin) {
            int mid= (begin+end)/2;
            mergeSort(arr,begin,mid,temp);
            mergeSort(arr,mid+1,end,temp);
            int left = begin;
            int right = mid+1;
            int index = 0;
            while (left <= mid && right <= end) {
                if (arr[left]<arr[right]) {
                    temp[index++] = arr[left++];
                }else{
                    temp[index++] = arr[right++];
                }
            }
            while (left <= mid) {
                temp[index++] = arr[left++];
            }
            while (right <= end) {
                temp[index++] = arr[right++];
            }
            index = 0;
            while (begin <= end) {
                arr[begin++] = temp[index++];
            }
        }
    }

 

七、基数排序

private static void radixSort(int arr[]){
        //找到最大数取位数
        int max = arr[0];
        for (int i : arr) {
            if (i>max) {
                max = i;
            }
        }
        int maxLength = (""+max).length();
        //按照依次按照个十百千万位放入对应的桶中再取出
        int[][] bucket = new int[10][arr.length];
        int[] bucketCount = new int[10];
        int radix = 1;
        int index = 0;
        for (int i = 0; i < maxLength; i++) {
            for (int j : arr) {
                int base = j / radix % 10;
                bucket[base][bucketCount[base]++] = j;
            }
            for (int j = 0; j < 10; j++) {
                for (int k = 0; k < bucketCount[j]; k++) {
                    arr[index++] = bucket[j][k];
                }
            }
            radix*=10;
            index=0;
            bucketCount = new int[10];
        }
    }

 

八、堆排序

private static void heapSort(int[] arr){
        //从第一个非叶子结点,从下向上构建大顶堆
        for (int i = (arr.length-1-1)/2; i >=0; i--) {
            heapAdjust(arr,i,arr.length);
        }
        //第一个元素和第i个对调,然后重新构造大顶堆
        for (int i = arr.length-1; i >0 ; i--) {
            int temp = arr[0];
            arr[0] = arr[i];
            arr[i] = temp;
            heapAdjust(arr,0,i);
        }
    }

    private static void heapAdjust(int[] arr,int index,int length){
        //这个就是插入排序思路,从下向上构建有序的大顶堆
        int temp = arr[index];
        //一个元素的左子节点时2n+1
        for (int i = index*2+1; i <length ; i=i*2+1) {
            //比较左右节点,找出较大子节点进行对比
            if (i+1<length&&arr[i]<arr[i+1]) {
                i++;
            }
            //子节点比当前节点大
            if (temp>=arr[i]) {
                break;
            //子节点比当前节点小,当前节点被子节点覆盖,指针下移
            }else {
                arr[index] = arr[i];
                index = i;
            }
        }
        arr[index] = temp;
    }

 

posted @ 2021-02-06 21:15  扶不起的刘阿斗  阅读(49)  评论(0编辑  收藏  举报