常见的排序问题
[本篇文章主要介绍入门级别排序]
- 问题: 一个整型数组
int[] a = {2,5,1,4,3};
要求对其排序
- 冒泡排序
- 冒泡排序是比较简单的排序,因为其排序过程类似于气泡的上浮,故此起名
- 算法剖析:
简单来说–》就是俩俩比较,将最大值放在最后或者将最小值放在最开始都可以,常用将最大值放在最后
详细来说–》拿出0位置数字与1位置数字进行比较,0位置数字大于1位置数字就交换俩个数字之间的位置(小于等于就不交换位置,下面的比较也是一样),然后1位置数字和2位置数字进行比较,1位置数字大于2位置数字就交换,每次比较数字位置都加1,结束条件:[一直比较到最后位置数字,确定出整个数组的最大值,在进行下一轮比较],
那下一轮的比较就可以只比较除了数组最大值的其他数字,比较出第二大的数字,放在倒数第二位,依次依次进行比较- 多说无用上菜:第一轮比较
- 第一次比较 --》2,5,1,4,3(2和5比较,没有发生变化)
- 第二次发生比较 --》2,5,1,4,3(5和1进行比较,发现5>1,交换俩数字的位置)-- 交换后:2,1,5,4,3
- 第三次发生比较 --》2,1,5,4,3(5和4进行比较,发现5>4,交换俩数字的位置) – 交换后 2,1,4,5,3
- 第四次发生比较 --》2,1,4,5,3(5和3进行比较,发现5>3,交换俩数字的位置) – 交换后 2,1,4,3,5
第一轮比较结束,确认出最大值5,此时数组顺序为
2,1,4,3,5
第二轮比较(现数组2,1,4,3,[5])因为现在数组中已经确定最大值5,所以这次比较直接比较前四个数即可
第一次比较 --》2,1,4,3,[5](2和1比较,发现2>1,交换俩数字的位置)-- 交换后:1,2,4,3,[5]
第二次进行比较 --》 1,2,4,3,[5] (2和4比较,没有发生变化)
第三次进行比较 --》 1,2,4,3,[5](4和3比较,发现4>3,交换俩数字的位置)-- 交换后:1,2,3,4,[5]
第二轮比较结束,确认出第二大的值4,此时数组的顺序为
1,2,3,4,5
第三轮比较,确认出第三大的值3,此时数组的顺序为
1,2,3,4,5
第四轮比较,确认出第四大的值2,此时数组的顺序为
1,2,3,4,5
(虽然从第二轮比较后数组顺序未发生改变,但是遍历比较还是在进行。思考:
重复的比较) 整体比较结束1,2,3,4,5
3.总结 :我们发现,冒泡排序其实真的就像浮起的泡泡,一层层向上飘,将最大的泡泡置顶,第二大的泡泡放到第二个位置,依次排序比较
代码演示:
- 选择排序
算法剖析:通过遍历数组将第一个数值与剩余数值比较拿出最大值或者最小值,与冒泡排序的区别就是选择排序是取出一个数字和其他剩余的数值进行
一一
比较(外层循环),而冒泡排序是俩俩
比较遍历(内层循环)继续整:第一轮比较
- 第一次比较 --》2,5,1,4,3(2和5比较,没有发生变化)
- 第二次发生比较 --》2,5,1,4,3(2和1进行比较,发现2>1,这时最小值为1)
- 第三次发生比较 --》2,5,1,4,3(拿当前最小值1和4进行比较,没有发生变化)
- 第四次发生比较 --》2,5,1,4,3(拿当前最小值1和3进行比较,没有发生变化)
第一轮比较结束,确认出最小值1,交换最小值与0位置数值的位置,此时顺序为
1,5,2,4,3
第二轮比较,此时确定最小值为1,排除掉这个数值,从下一个进行相同比较
- 第一次发生比较 --》[1],5,2,4,3(5和2进行比较,5>2,当前最小值变为2)
第二次发生比较 --》[1],5,2,4,3(拿当前最小值2和4进行比较,没有发生变化)
第三次发生比较 --》[1],5,2,4,3(拿当前最小值2和3进行比较,没有发生变化)第二轮比较结束,确认出当前最小值2 ,交换5与2的位置,现在的顺序就变为了
1,2,5,4,3
第三轮比较结束,确认出当前最小值3,当前数组顺序为
1,2,3,4,5
第四轮比较结束,确认出当前最小值4,当前数组顺序为
1,2,3,4,5
当数组只剩一个数值为比较时,就可以停止比较了,整体顺序
1,2,3,4,5
(思考:
重复比较)总结:选择排序其实就是依次选择每个数值进行
一一
比较,选出最大值或者最小值放到0位置
代码演示:
- 插入排序
- 算法剖析:类似于冒泡排序的俩俩比较,但仅此而已,不同的是–当前一个数值与后一个数值发生交换后,这个交换过来的数值要与前面的数值进行比较交换
- 接着整:第一轮比较
- 第一次比较 --》2,5,1,4,3,(2和5比较,没有发生变化)
- 第二次比较 --》2,5,1,4,3,(5和1进行比较,5>1交换位置),交换后2,1,5,4,3
- 第三次比较 – 》2,1,5,4,3,这时候我们就需要
从头再来
,一直到交换数值的位置(2和1进行比较,2>1交换位置),交换后1,2,5,4,3- 第四次比较 --》1,2,5,4,3 ,从5位置开始向后比较(5和4比较,5>4交换位置),交换后1,2,4,5,3
- 第五次比较 --》 1,2,4,5,3,从交换过来的4向前比较(重复1步骤进行比较先1,2进行比较没有发生变化,在2,4进行比较没有发生变化)
- 第六次比较 1,2,4,5,3, 从当前数值5位置继续向后比较(5和3比较,5>3交换位置),交换后 1,2,4,3,5
- 第七次进行比较 1,2,4,3,5 ,
从头再来
(1,2进行比较没有发生变化,2,4进行比较没有发生变化,4,3进行比较,4>3交换位置[交换位置之后又要从头
进行比较]),交换后1,2,3,4,5
这时我们会发现想要继续向下比,5的后面已经没有数值了,这样即说明,排好了
(思考:重复比较,共比较了多少次 )总结:插入排序其实就是俩俩比较,交换后要
从头再来
代码演示:
- 简单的桶排序
- 算法剖析:因为这个排序只涉及一点点的桶排序思想,所以不是很难,首先分桶,根绝给定的数字划分不同范围的桶,给定每个桶一个固定的编号,将桶从大到小进行排列,将数值放到固定桶中,根据桶的标号就可以得出数值排列大小
不跑流程了,直接上代码
//简单的桶排序
int[] a = {3, 4, 3, 6, 5, 5};
//制作桶限制每个桶的范围
Map<Integer, Integer> bucket = new HashMap<>();
for (int i = 1; i < 11; i++) {
bucket.put(i, 0);
}
//将对应数字存入桶中,key代表数字桶标志,val代表数量
for (int i = 0; i < a.length; i++) {
if (bucket.containsKey(a[i])) {
bucket.put(a[i], bucket.get(a[i]) + 1);
}
}
//遍历取出即可
Set<Integer> i = bucket.keySet();
Integer t = null;
for (Integer s : i) {
t = bucket.get(s);
if (t != 0) {
if (t > 1) {
for (int j = 0; j < t; j++) {
System.out.print(s + " ");
}
} else {
System.out.print(s + " ");
}
}
}