数据结构与算法系列十七(计数排序)

北城余情 提交于 2020-04-19 10:37:23

1.引子

1.1.为什么要学习数据结构与算法?

有人说,数据结构与算法,计算机网络,与操作系统都一样,脱离日常开发,除了面试这辈子可能都用不到呀!

有人说,我是做业务开发的,只要熟练API,熟练框架,熟练各种中间件,写的代码不也能“飞”起来吗?

于是问题来了:为什么还要学习数据结构与算法呢?

#理由一:
	面试的时候,千万不要被数据结构与算法拖了后腿
#理由二:
	你真的愿意做一辈子CRUD Boy吗
#理由三:
	不想写出开源框架,中间件的工程师,不是好厨子

1.2.如何系统化学习数据结构与算法?

我想好了,还是需要学习数据结构与算法。但是我有两个困惑:

1.如何着手学习呢?

2.有哪些内容要学习呢?

学习方法推荐:

#学习方法
1.从基础开始,系统化学习
2.多动手,每一种数据结构与算法,都自己用代码实现出来
3.思路更重要:理解实现思想,不要背代码
4.与日常开发结合,对应应用场景

学习内容推荐:

数据结构与算法内容比较多,我们本着实用原则,学习经典的、常用的数据结构、与常用算法

#学习内容:
1.数据结构的定义
2.算法的定义
3.复杂度分析
4.常用数据结构
	数组、链表、栈、队列
	散列表、二叉树、堆
	跳表、图
5.常用算法
	递归、排序、二分查找
	搜索、哈希、贪心、分治
	动态规划、字符串匹配

2.考考你

上一篇:数据结构与算法十六(桶排序)中,我们知道了桶排序是一个高效的排序算法,它的时间复杂度是:O(n)。桶排序适合于对大规模的数据量进行排序,只要满足前提条件:数据分布相对均匀,也就是说分桶后,每个桶的数据量均衡。

这一篇我们再来看另外一个高效的排序算法,它是桶排序的一个变种:计数排序,它的时间复杂度也是:O(n)

#考考你:
1.你知道计数排序实现的思想吗
2.你能用java实现计数排序吗

3.案例

3.1.计数排序实现思想

计数排序,是桶排序的一个特列。我们先看一个例子,只要你理解了这个例子,你也就理解了计数排序适合的场景,以及它的实现思想。

例子:

1.快要一年一度的高考了,我们以给考生考试成绩排序为例

2.假如全省有100万考生参加考试,满分是750。如何实现根据考生考试成绩进行排名

3.根据桶排序原理,以及考试分数范围:0-750。可以分751个桶

4.每个桶用于存放对应分数的考生数量。比如a[0],表示0分的考生数量

5.扫描待排序数组array[n],通过桶(计数数组)count[max-min],对每个array[n] 中出现的元素,进行计数

6.扫描计数数组count[max-min],还原数组array[n]。排序结束

 

这个例子不难理解,我们抓一下关键点:

#实现思想关键要点:
1.以考生的分数进行分桶,每个桶存放对应分数的考生数量;
2.扫描待排序数组array[n],统计计数每个桶(分数)对应的考生数量
3.扫描计数数组(桶),还原数组array[n]。此时array[n]中的数据,即已经按照考生分数排好序

文字描述总要差那么点感觉,大家都是程序员,直接上代码,相信你就能理解了。

3.2.计数排序代码实现

3.2.1.主体代码

package com.anan.algorithm.sort;

import java.util.Arrays;

/**
 * 计数排序:
 *  1.思想:
 *      1.1.计数排序,是桶排序的一个特例
 *      1.2.假如全省有100万考生参加考试,满分是750。如何实现根据考生考试成绩进行排名
 *      1.3.实现思路:
 *          1.3.1.根据桶排序原理,以及考试分数范围:0-750。可以分751个桶
 *          1.3.2.每个桶用于存放对应分数的考生数量。比如a[0],表示0分的考生数量
 *          1.3.3.这里通过数组来代表桶
 *          1.3.4.扫描待排序数组array[n],通过桶(计数数组)count[max-min],对每个array[n]
 *          中出现的元素,进行计数
 *          1.3.5.扫描计数数组count[max-min],还原数组array[n]。排序结束
 *
 *  2.时间复杂度:
 *      O(n)
 *  3.空间复杂度:
 *      O(m):m是桶的个数
 */
public class CountingSort {
    public static void main(String[] args) {
        // 1.定义待排序数组(这里假设分数范围:0-20)
        Integer[] array = {1,6,3,4,2,5,9,8,10,7,11,20,17,16,15,18,19,2,3,1,9,8,6,1,20};
        int n = array.length;
        System.out.println("1.待排序数组元素个数:" + n +",元素内容:" + Arrays.asList(array));

        // 2.定义计数数组(桶)
        Integer[] count = new Integer[21];
        for (int i = 0; i < count.length; i++) {
            count[i] = 0;
        }

        // 3.关键步骤一:计数
        //扫描待排序数组array[n],通过桶(计数数组)count[max-min],对每个array[n]中出现的元素,进行计数
        for(int i = 0; i < array.length; i++){
            count[array[i]] ++;
        }

        System.out.println("2.计数数组元素个数:" + count.length +",元素内容:" + Arrays.asList(count));

        // 4.关键步骤二:还原
        //扫描计数数组count[max-min],还原数组array[n]。排序结束
        Integer[] sortResult = new Integer[array.length];
        int k = 0;
        for (int i = 0; i < count.length; i++) {
            if(count[i] > 0){
                for (int j = 0; j < count[i]; j++) {
                    sortResult[k++] = i;
                }
            }

        }

        System.out.println("3.排序后数组元素个数:" + n +",元素内容:" + Arrays.asList(sortResult));

    }
}

3.2.2.测试结果

D:\02teach\01soft\jdk8\bin\java 
    com.anan.algorithm.sort.CountingSort
1.待排序数组元素个数:25,元素内容:[1, 6, 3, 4, 2, 5, 9, 8, 10, 7, 11, 20, 17, 16, 15, 18, 19, 2, 3, 1, 9, 8, 6, 1, 20]
2.计数数组元素个数:21,元素内容:[0, 3, 2, 2, 1, 1, 2, 1, 2, 2, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 2]
3.排序后数组元素个数:25,元素内容:[1, 1, 1, 2, 2, 3, 3, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10, 11, 15, 16, 17, 18, 19, 20, 20]

Process finished with exit code 0

4.讨论分享

#考考你答案:
1.你知道计数排序实现的思想吗
	【参考】3.1计数排序实现思想
2.你能用java实现计数排序吗
	【参考】3.2计数排序代码实现

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!