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计数排序代码实现
来源:oschina
链接:https://my.oschina.net/u/4450329/blog/3274648