1.冒泡排序(最简单,性能最差的排序方法)
两两做比较,第一轮下来找不到最小的值
1.外层循环控制行,内层循环控制列,循环的嵌套
var arr = [5,99,2,9,1,5,67,7,10,23];
for(var i = 0;i < arr.length-1;i++){ //大循环,用于遍历数组每个元素
for(var j = 0;j < arr.length-i-1;j++){ //小循环,用于将数组中的某个元素与其它所有元素相比较
var sum; //声明一个局部变量,当作第三个空瓶子
if(arr[j] > arr[j+1]){ //判断当前元素和后一个元素的大小,如果当前元素比后一个元素大
sum = arr[j+1]; //将后一个元素(小元素)放在空瓶子里
arr[j+1] = arr[j]; //将当前元素(大元素)放在后一个元素的位置
arr[j] = sum; //将小元素从空瓶子中拿出来,放在当前元素的位置
}
}
}
console.log(arr)
2.选择排序
选择排序是从数组的开头开始,将第一个元素和其他元素作比较,检查完所有的元素后,最小的放在第一个位置,接下来再开始从第二个元素开始,重复以上一直到最后
var arr = [5,99,2,9,1,5,67,7,10,23] //定义一个杂乱的数组
for(var i=0;i<arr.length-1;i++){//大循环,需要比对的次数
var min = arr[i]; //假定一个最小值
var minIndex = i; //假定最小值的索引
for(var j=i+1;j<arr.length;j++){//小循环,每次需要比对的次数
if(min>arr[j]){ //判断最小值是否为真的最小值
min = arr[j]; //获取真正的最小值
minIndex = j; //获取真正最小值的索引
}
}
arr[minIndex] = arr[i]; //将当前元素放在最小值的位置
arr[i] = min; //将最小值放在当前元素的位置
}
console.log(arr);//输入排序好的数组
3.插入排序(小型数组的时候,优于冒泡和选择)
插入排序的工作原理就是将未排序数据,对已排序数据序列从后向前扫描,找到对应的位置并插入。插入排序通常采用占位的形式,空间复杂度为O(1),因此,在从后向前扫描的过程中,需要反复的把已排序的元素逐步向后挪位,为新插入元素提供插入的位置。
https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/8/14/16538fc898df137f~tplv-t2oaga2asx-watermark.awebp
function insertSort(arr) {
for(let i = 1; i < arr.length; i++) { //外循环从1开始,默认arr[0]是有序段
for(let j = i; j > 0; j--) { //j = i,将arr[j]依次插入有序段中
if(arr[j] < arr[j-1]) {
[arr[j],arr[j-1]] = [arr[j-1],arr[j]];
} else {
break;
}
}
}
return arr;
}
1.i是外循环,依次把后面的数插入前面的有序序列中,默认arr[0]为有序的,i就从1开始
2.j进来后,依次与前面队列的数进行比较,因为前面的序列是有序的,因此只需要循环比较、交换即可
3.注意这里的break,因为前面是都是有序的序列,所以如果当前要插入的值arr[j]大于或等于arr[j-1],则无需继续比较,直接下一次循环就可以了。
4.快速排序 最常用的排序算法,复杂度为O(nlogn),性能通常比其他的复杂度为O(nlogn)的排序算法要好。
快速排序是对冒泡排序的一种改进,它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
说白了就是从一个数组中找到一个中间数,以他为中心把比他大的放左边,把比他小的放在右边,然后分别对左右两边在进行排序,排序完成之后合并在一起
var quickSort2 = function(arr) {
console.time('2.快速排序耗时');
if (arr.length <= 1) { return arr; }
var pivotIndex = Math.floor(arr.length / 2);
var pivot = arr.splice(pivotIndex, 1)[0];
var left = [];
var right = [];
for (var i = 0; i < arr.length; i++){
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
console.timeEnd('2.快速排序耗时');
return quickSort2(left).concat([pivot], quickSort2(right));
};
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(quickSort2(arr));//[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
5、归并排序。(归并排序是第一个可以被实际使用的排序算法,其复杂度为O(nlogn)。fireFox中Array.prototype.sort方法基于这个算法实现)
1.首先将原始数组分割直至只有一个元素的子数组,然后开始归并。归并过程也会完成排序,直至原始数组完全合并并完成排序。
function mergeSort(array) {
var length = array.length;
if (length === 1) {
return array;
}
var mid = Math.floor(length/2);
var left = array.slice(0, mid);
var right = array.slice(mid, length);
return merge(mergeSort(left),mergeSort(right))
}
function merge(left, right) {
var result = [];
let il = 0, ir = 0;
while(il < left.length && ir < right.length){
if(left[il] < right[ir]){
result.push(left[il]);
il++;
}else {
result.push(right[ir]);
ir++;
}
}
while (il < left.length){
result.push(left[il]);
il++;
}
while (ir < right.length){
result.push(right[ir]);
ir++;
}
return result;
}
6.总结:
1.快速排序和归并排序都是分治的方法,把数组分成若干个只有一个元素的数组再合并。
2.快速排序:是先选择一个基准对数组进行分割,这个过程已经进行了部分排序。
3.归并排序:是直接对数组进行分割,分完之后再合并的时候排序
https://juejin.cn/post/6844903444365443080#heading-18