javascript|ES6实现冒泡,快排算法(附代码)
冒泡排序(Bubble Sort)
- 冒泡排序它在所有排序算法中最简单。然而, 从运行时间的角度来看,冒泡排序是最差的一个,它的复杂度是O(n2)。
- 冒泡排序比较任何两个相邻的项,如果第一个比第二个大,则交换它们。元素项向上移动至正确的顺序,就好像气泡升至表面一样,冒泡排序因此得名。
- 交换时,我们用一个中间值来存储某一交换项的值。其他排序法也会用到这个方法,因此我 们声明一个方法放置这段交换代码以便重用。使用ES6(ECMAScript 2015)**增强的对象属性——对象数组的解构赋值语法,**这个函数可以写成下面 这样:
[array[index1], array[index2]] = [array[index2], array[index1]];
具体实现:
function bubbleSort(arr) {
for (let i = 0; i < arr.length; i++) {//外循环(行{2})会从数组的第一位迭代 至最后一位,它控制了在数组中经过多少轮排序
for (let j = 0; j < arr.length - i; j++) {//内循环将从第一位迭代至length - i位,因为后i位已经是排好序的,不用重新迭代
if (arr[j] > arr[j + 1]) {//如果前一位大于后一位
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];//交换位置
}
}
}
return arr;
}
快速排序
快速排序也许是最常用的排序算法了。它的复杂度为,且它的性能通常比其他的复 杂度为O(nlog n )的排序算法要好。
特殊情况:left>right,直接退出。
步骤:
(1) 首先,从数组中选择中间一项作为主元base,一般取第一个值。
(2) 创建两个指针,左边一个指向数组第一个项,右边一个指向数组最后一个项。移动右指针直到找到一个比主元小的元素,接着,移动左指 针直到我们找到一个比主元大的元素,然后交 换它们,重复这个过程,直到左指针遇见了右指针。这个过程将使得比主元小的值都排在主元之前,而比主元大的值都排在主元之后。这一步叫作划分操作。
(3)然后交换主元和指针停下来的位置的元素(等于说是把这个元素归位,这个元素左边的都比他小,右边的都比他大,这个位置就是他最终的位置)
(4) 接着,算法对划分后的小数组(较主元小的值组成的子数组,以及较主元大的值组成的 子数组)重复之前的两个步骤(递归方法),
递归的出口为left/right=i
,也就是:
left>i-1 / i+1>right
此时,子数组数组已排序完成。
归位示意图:
具体实现:
function quicksort(arr, left, right) {
if (left > right) {
return;
}
var i = left,
j = right,
base = arr[left]; //基准总是取序列开头的元素
// var [base, i, j] = [arr[left], left, right]; //以left指针元素为base
while (i != j) {
//i=j,两个指针相遇时,一次排序完成,跳出循环
// 因为每次大循环里面的操作都会改变i和j的值,所以每次循环/操作前都要判断是否满足i<j
while (i < j && arr[j] >= base) {
//寻找小于base的右指针元素a,跳出循环,否则左移一位
j--;
}
while (i < j && arr[i] <= base) {
//寻找大于base的左指针元素b,跳出循环,否则右移一位
i++;
}
if (i < j) {
[arr[i], arr[j]] = [arr[j], arr[i]]; //交换a和b
}
}
[arr[left], arr[j]] = [arr[j], arr[left]]; //交换相遇位置元素和base,base归位
// let k = i;
quicksort(arr, left, i - 1); //对base左边的元素递归排序
quicksort(arr, i + 1, right); //对base右边的元素递归排序
return arr;
}