美文网首页
数据结构与算法学习-排序算法(二)

数据结构与算法学习-排序算法(二)

作者: Kip_Salens | 来源:发表于2019-03-22 18:37 被阅读0次

很早之前整理过一篇排序算法,这次又整理了一下,增加了计数排序、归并排序和桶排序,需要的拿走不谢!

各种排序算法实现

public class Sort {

    /**
     * 交换数组中两个位置的数值
     *
     * @param arr
     * @param i
     * @param j
     */

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


    /**
     * 冒泡排序
     *
     * @param arr 数组
     */
    public static void bubbleSort(int[] arr) {
        if (arr == null) {
            return;
        }
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    swap(arr, j, j + 1);
                }
            }
        }
    }

    /**
     * 插入排序
     * 要点:像扑克牌一样,小牌放在左边,插入的牌比左边的某张牌大(左边的牌已经排好大小),
     * 该张牌后面的牌依次向右移动一个位置
     *
     * @param arr 数组
     */
    public static void insertSort(int[] arr) {
        if (arr == null) {
            return;
        }
        for (int i = 1; i < arr.length; i++) {
            int temp = arr[i];
            int j = i - 1;
            while (j >= 0 && arr[j] > temp) {
                arr[j + 1] = arr[j];
                j--;
            }
            arr[j + 1] = temp;
        }
    }

    /**
     * 选择排序
     * 每次选择一个最小(或最大)的数,拿走,再从剩下的数中重复选择最小(或最大)的数
     *
     * @param arr 数组
     */
    public static void selectSort(int[] arr) {
        if (arr == null) {
            return;
        }
        for (int i = 0; i < arr.length - 1; i++) {
            int min = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[min]) {
                    min = j;
                }
            }
            swap(arr, min, i);
        }
    }

    /**
     * 快速排序算法
     *
     * @param arr   数组
     * @param left  左边索引
     * @param right 右边索引
     */
    public static void quickSort(int[] arr, int left, int right) {

        if (left > right) {
            return;
        }
        int index = pivot(arr, left, right);
        quickSort(arr, left, index - 1);
        quickSort(arr, index + 1, right);
    }

    /**
     * @param arr
     * @param left
     * @param right
     * @return
     */
    private static int pivot(int[] arr, int left, int right) {
        int i = left;
        int j = right;
        int pivot = arr[left];

        while (i != j) {
            while (arr[j] >= pivot && i < j) {
                j--;
            }
            while (arr[i] <= pivot && i < j) {
                i++;
            }
            if (i < j) {
                swap(arr, i, j);
            }
        }
        arr[left] = arr[i];
        arr[i] = pivot;
        return i;
    }

    /**
     * 一个长度为 n 的 double 类型数组,取值为 0 - 10,要求快速将这 20 个 double 元素从小到大排序
     *
     * @param arr       double 数组
     * @param bucketNum 桶的数量
     */
    public static void bucketSort(double[] arr, int bucketNum) {
        if (arr == null) {
            return;
        }
        double max = arr[0];
        double min = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
            if (arr[i] < min) {
                min = arr[i];
            }
        }
        // 间隔
        double d = max - min;

        // 创建桶
        List<LinkedList<Double>> bucketList = new ArrayList<>();
        for (int i = 0; i < bucketNum; i++) {
            bucketList.add(new LinkedList<>());
        }

        // 将数据放入桶中
        for (int i = 0; i < arr.length; i++) {
            int index = (int) ((arr[i] - min) / d * (bucketNum - 1));
            bucketList.get(index).add(arr[i]);
        }

        // 对每个桶排序
        for (LinkedList<Double> linkedList : bucketList) {
            Collections.sort(linkedList);
        }

        // 输出数据
        int i = 0;
        for (LinkedList<Double> linkedList : bucketList) {
            for (Double number : linkedList) {
                arr[i++] = number;
            }
        }
    }

    /**
     * 计数排序
     *
     * @param arr 数组
     */
    public static int[] countSort(int[] arr) {
        if (arr == null) {
            return null;
        }
        int max = arr[0];
        int min = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
            if (arr[i] < min) {
                min = arr[i];
            }
        }

        // 创建统计数组,并对每个数据进行计数
        int d = max - min;
        int[] countArr = new int[d + 1];
        for (int i = 0; i < arr.length; i++) {
            countArr[arr[i] - min]++;
        }

        // 对统计数组累计求和
        int sum = 0;
        for (int i = 0; i < countArr.length; i++) {
            sum += countArr[i];
            countArr[i] = sum;
        }

        int[] sortArr = new int[arr.length];
        for (int i = arr.length - 1; i >= 0; i--) {
            sortArr[countArr[arr[i] - min] - 1] = arr[i];
            countArr[arr[i] - min]--;
        }
        return sortArr;
    }

    /**
     * 归并排序
     *
     * @param arr 数组
     */
    public static void mergeSort(int[] arr) {
        if (arr == null) {
            return;
        }
        int[] temp = new int[arr.length];
        mergeSort(arr, 0, arr.length - 1, temp);
    }

    private static void mergeSort(int[] arr, int left, int right, int[] temp) {
        if (left < right) {
            int mid = (left + right) >> 1;
            mergeSort(arr, left, mid, temp);
            mergeSort(arr, mid + 1, right, temp);
            merge(arr, left, mid, right, temp);
        }
    }

    private static void merge(int[] arr, int left, int mid, int right, int[] temp) {
        int i = left;
        int j = mid + 1;
        int t = 0;
        while (i <= mid && j <= right) {
            if (arr[i] <= arr[j]) {
                temp[t++] = arr[i++];
            } else {
                temp[t++] = arr[j++];
            }
        }
//        while(i<=mid){//将左边剩余元素填充进temp中
//            temp[t++] = arr[i++];
//        }
//        while(j<=right){//将右序列剩余元素填充进temp中
//            temp[t++] = arr[j++];
//        }
//        t = 0;
//        //将temp中的元素全部拷贝到原数组中
//        while(left <= right){
//            arr[left++] = temp[t++];
//        }
        if (i <= mid) {
            System.arraycopy(arr, i, temp, t, mid - i + 1);
            t += mid - i;
        }
        if (j <= right) {
            System.arraycopy(arr, j, temp, t, right - j + 1);
            t += right - j;
        }
        if (left <= right){
            System.arraycopy(temp, 0, arr, left, t + 1);
        }
    }

}

算法这部分,需要长期练习,并将其使用的场景结合起来,才能深入理解,不容易忘!

代码地址

各种排序算法

相关文章

  • 数据结构和算法

    一。基本数据结构,排序算法,算法学习工具 基本数据结构,排序算法,算法学习工具(温馨提示:部分介绍需自备梯子) 二...

  • 排序算法-堆排序

    参考: Java排序算法(五):堆排序 【算法与数据结构】图说堆排序 【数据结构】排序算法:希尔、归并、快速、堆排...

  • (转)排序算法

    排序算法点这里 数据结构与算法——计数排序、桶排序、基数排序

  • 浅谈算法和数据结构

    注:采转归档,自己学习查询使用 浅谈算法和数据结构: 一 栈和队列浅谈算法和数据结构: 二 基本排序算法浅谈算法和...

  • Hash算法

    数据结构与算法分析:大纲数据结构:数组算法:hash算法算法:排序算法Java实现 1 Hash算法? 将任意长度...

  • 算法与数据结构(六):堆排序

    title: 算法与数据结构(六):堆排序tags: [算法与数据结构, C语言, 堆排序]date: 2019-...

  • 算法与数据结构路线图

    学习算法与数据结构,深刻理解计算机科学 排序算法:插入、冒泡、选择、希尔、快速、归并、堆排序、计数排序、桶排序、基...

  • 数据结构与算法学习笔记之 适合大规模的数据排序

    数据结构与算法学习笔记之 适合大规模的数据排序 前言 在数据排序的算法中,不同数据规模应当使用合适的排序算法才能达...

  • python 简单排序

    数据结构与算法 01 我们通常所说的排序算法往往指的是内部排序算法,即数据记录在内存中进行排序。 排序算法大体可分...

  • 一步一步学习数据结构和算法(一) O(n2) 排序算法

    排序算法 文中使用的图片来自慕课网课程算法与数据结构 为什么要学习 的排序算法 这是一种简单的算法, 但是不因为...

网友评论

      本文标题:数据结构与算法学习-排序算法(二)

      本文链接:https://www.haomeiwen.com/subject/igorvqtx.html