一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情。
前言
了解冒泡排序后接下来介绍一种新的排序算法:选择排序。通过选择排序来和冒泡排序作对比,比较一下两者排序效率如何以及各个优缺点。
选择排序
选择排序过程是在数组中找出最小值,然后一次从左到右做替换。
| 索引0 | 索引1 | 索引2 | 索引3 | 索引4 | 索引5 |
|---|---|---|---|---|---|
| 2 | 5 | 3 | 1 | 4 | 7 |
- 例如初始无序数组,首选一个
待定索引以及一个指向索引0,当前就先待定索引赋值为索引0因为目前它是最小值。
| 索引0 | 索引1 | 索引2 | 索引3 | 索引4 | 索引5 |
|---|---|---|---|---|---|
| 1 | 5 | 3 | 2 | 4 | 7 |
- 接着指向索引
索引1,待定索引赋值比索引1要大(2 > 1),待定索引赋值为索引1。 - 接着指向索引
索引2,继续和待定索引赋值数进行比较... - 直到轮回到最后,
待定索引赋值是当前数组最小值了,将待定索引的数据填入索引0,并将原索引0的数据替换到最小值的索引。 - 后续过程如上执行直到
待定索引指向索引5结束。
原理
冒泡排序比作相邻两个指针做比较的话,选择排序是一个指针指向数组,一个暂存下标来记录当前最小值。
| 2 | 5 | 3 | 1 | 4 | 7 |
|---|
指针指向索引0起始暂存下标记录是0,然后指针指向索引1 = 5,比暂存下标值要大,继续往后查询...直到找到值为1的索引3暂存下标变成3,接着继续往后得到当前最小值是1且是索引3。然后索引0和索引3数值交换。
以上过程结束后再进行下一步指针指向索引1始暂存下标记录是1,继续如上过程找出最小的值,然后索引1和索引X数值交换。
算法代码
i表示数组循环次数,j表示当前指针指向。min作为当前最小值下标记录。
void main(){
int min;
int[] datas;
for(int i=0;i<datas.length - 1;i++){
min = i;
for(int j= i + 1;j<datas.length;j++){
if(datas[min] > datas[j]){
min = j;
}
}
if(min != i){
int temp = datas[min];
datas[min] = datas[i];
datas[i] = temp;
}
}
}
假设N个数据执行以上算法 可推导出大O记法为O()。 选择排序在此过程中每次循环最坏情况交换次数只有一次,而冒泡排序每次循环最坏情况每次都需要进行一次排序。从实际数据统计上看选择排序效率会比冒泡排序快上一倍。
大O忽略常数
因此选择排序最优情况下大O记法为O(),但实际情况选择排序和冒泡排序一样记作O()。
- 大O记法一般不包含数字(指数等其他情况例外),比如O()记作O(),O()也会被记作O()。
- 当在大数据情况下以上可以这么考虑忽略,但实际情况下当然快100倍200倍的算法当然是选择更快的。
- 存在临界点的原因大O记法会忽略常数,大O不关心临界点位置它只表明在总体情况下一类算法会比一类算法快。