目录
一、冒泡排序
冒泡算法是最易懂的排序算法,它实现简单,但是效率较低,适合n较小时使用。
基本思路:
依次比较相邻的两个数,如果不符合排序规则,则调换两个数的位置。先比较一轮一次,再用循环比较一轮多次,得到最大(或最小)的数排在最后一位,然后加循环比较多轮多次,得到最终的排序结果。
以对数组[4,3,5,1,2]进行从小到大排序为例,步骤如下:
①比较第一位的“4”和第二位的“3”,4>3,交换位置;再将第二位的“4”和第三位的“5”进行比较,4<5,位置不变;接着将第三位的“5”和第四位的“1”进行比较,5>1,交换位置;最后将第四位的“5”和第五位的“2”进行比较,5>2,交换位置。
②数组变成[3,4,1,2,5],可以看到最大的数"5"已经在数组最后一位,即代表第一轮排序结束,数组最后一位不会再变。
③接着重复步骤①,得到数组倒数第二位上的数字即数组中第二大的数,数组变成[3,1,2,4,5],第二轮排序结束,数组倒数第二位不会再变。
④接着再重复步骤①,得到数组倒数第三位上的数字即数组中第三大的数,数组变成[1,2,3,4,5],第三轮排序结束,数组倒数第三位不会再变。
⑤虽然可以看到到步骤④我们已经得到了从小到大排列的数组,但是系统还没有执行完毕。还需要再重复步骤①,直到剩下最后一个位置即确定数组的第一位不会再变的时候,所有排序才得以结束。
时间复杂度:O(n2)
例:对数组[38,26,89,56,17,44]所有元素进行从小到大排序。
代码实现:
function bubbleSort(arr){
for(var i=0;i<arr.length;i++){
for(var j=0;j<arr.length;j++){
if(arr[j]>arr[j+1]){
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
return arr;
}
var arr = [38,26,89,56,17,44];
console.log("冒泡排序前的数组是:",arr);
arr = bubbleSort(arr);
console.log("冒泡排序后的数组是:",arr);
实现效果如下:
二、选择排序
选择排序时表现最稳定的排序算法之一,它的优点在于不占用额外的内存空间。
基本思路:
与冒泡排序类似,也是依次对相邻的数字进行两两比较。它们的不同之处在于选择排序不会每比较一次就调换位置,而是一轮比较完毕,找到最大(或最小)值之后,将其放在正确的位置,其他数的位置不变。
先假设数组第一位是最大(或最小)值,用该最值与数组其他值进行比较,若与排序规则不相符,则替换最值,第一轮排序在未排序序列中找到最大(或最小)值,存放在排序序列的起始位置;然后,再从剩余未排列元素中继续寻找最大(或最小)值,放到已排序列的末尾。以此类推,直到所有元素均排序完毕。
以对数组[4,3,5,1,2]进行从小到大排序为例,步骤如下:
①假定数组第一位的“4”是最小值。
②用最小值“4“和第二位的”3“进行比较,4>3,所以新的最小值是第二位的”3“;
③用最小值”3“和第三位的”5“进行比较,3<5,最小值不变;
④用最小值”3“和第四位的”1“进行比较,3>1,所以新的最小值是第四位的”1“;
⑤用最小值”1“和第五位的”2“进行比较,1<2,最小值不变;
⑥将第四位的”1“和第一位的”4“交换位置,数组变成[1,3,5,4,2],第一轮比较结束,数组第一位是最小值”1“,不会再变;
⑦对剩下的[3,5,4,2]重复上面的步骤①-⑥,每一轮排序都会将该轮的最小值排到正确的位置,直到剩下最后一个位置,所有排序结束。
时间复杂度:O(n2)
例:对数组[38,26,89,56,17,44]所有元素进行从小到大排序。
代码实现:
function selectSort(arr){
var min,temp;
for(var i=0;i<arr.length;i++){
min = i;
for(var j=i+1;j<arr.length;j++){
if(arr[j]<arr[min]){
min = j;
}
}
temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
return arr;
}
var arr = [38,26,89,56,17,44];
console.log("选择排序前的数组是:",arr);
arr = selectSort(arr);
console.log("选择排序后的数组是:",arr);
实现效果如下: