案例引入
为什么会写这篇博客呢?因为我在初学选择法排序和冒泡排序之后做的练习中混淆了二者。
具体代码如下:
- 要求:利用选择法排序将数组[45,78,21,30,89,76]从小到大排序
// 选择法排序
var arr = [45,78,21,30,89,76]
for(var i = 0;i<arr.length;i++){ //外循环控制趟数
var min = arr[i] //假定最小值用于比较
for(var j = i+1;j<=arr.length;j++){ //j=i+1使其从剩余元素中进行筛查 //从剩余数字中寻找最小值
if(min > arr[j]){
min = arr[j] //更新最小值
var temp = arr[j] //交换a[j]和a[i]
arr[j] = arr[i]
arr[i] = temp
}
}
}
console.log(arr)
接下来我们先学习冒泡排序和选择法排序,学习完成后再来分析这个案例。
冒泡法
实现原理
代码演示
// 冒泡排序
var arr = [45,78,21,30,89,76]
var i = 0;
for(j = 0;j<arr.length;j++){
for(i = 0;i<arr.length-1;i++){
if(arr[i] > arr[i+1]){
var temp = arr[i]
arr[i] = arr[i+1]
arr[i+1] = temp
}
}
}
console.log(arr)
代码解析
- 外循环:控制循环趟数,即要进行几次大循环(找出一个最大值算一个大循环)。
- 内循环:控制每趟需要比较的次数
- if语句:进行相邻数字的比较和交换,最终将当前数组的最大值“冒出去”。
- 关键点:两两比较,即时交换
选择法
实现原理
代码演示
//选择法排序
var arr = [45,78,21,30,89,76]
for(var i = 0;i<=arr.length;i++){
var min = arr[i]
var k = i;
for(var j = i+1;j<arr.length;j++){
if(min > arr[j]){
min = arr[j]
k = j;
}
}
if(k!=i){
var temp = arr[k]
arr[k] = arr[i]
arr[i] = temp
}
}
console.log(arr)
代码解析
- 外循环:控制循环趟数,即要进行几次大循环(找出一个最小值算一个大循环)。
- 内循环:控制每趟需要比较的次数
- 第一条if语句:比较当前最小值和其他所有元素,记录最终的最小值。
- 第二条if语句:比较最小值和当前位置的数字,并决定是否交换,进入下一轮外循环。
- 关键点:先找最值,一次交换
案例分析
现在我们已经了解了冒泡排序和选择法排序,我们再回过头来分析一下一开始提到的案例:
- 要求:利用选择法排序将数组[45,78,21,30,89,76]从小到大排序
// 选择法排序
var arr = [45,78,21,30,89,76]
for(var i = 0;i<arr.length;i++){ //外循环控制趟数
var min = arr[i] //假定最小值用于比较
for(var j = i+1;j<=arr.length;j++){ //j=i+1使其从剩余元素中进行筛查 //从剩余数字中寻找最小值
if(min > arr[j]){
min = arr[j] //更新最小值
var temp = arr[j] //交换a[j]和a[i]
arr[j] = arr[i]
arr[i] = temp
}
}
}
console.log(arr)
- 乍一看这段代码,好像是选择法排序:设置最小值,在当前位置更新最小值。
- 但是再一看,发现这段代码在每次比较成功后就会进行交换,并不是选择法排序的“先找最值,一次交换”。
- 那么它是什么呢?我认为这是一种变形的冒泡排序。
- 虽然不是相邻元素的比较和交换,但它是“两两交换,及时执行”,我认为是一种变形的冒泡排序。
冒泡法和选择法的区别与优缺点
区别
- 冒泡排序:两两比较,即时交换。
- 选择法排序:先找最值,一次交换。
优缺点
- 冒泡排序:实现起来简单,如果待排序数据量小,并且对效率要求不高时,完全可以满足。
- 选择排序:交换次数较少,一定程度上提高了运算效率。