冒泡排序
冒泡的核心思想:每一轮确定一个最大的数放到最右边。就是双重for循环遍历,进行两两比较。
// 核心思想:每一轮比较,把一个数归位
function bubbleSort(arr, arrLength) {
// 1. i控制几轮 举个例子:10个数 最多进行9轮,因为当进行9轮后,第十个数是自动归位的不需要再比较
for (var i = 0; i < arrLength - 1; i++) {
// 2. j控制一轮中,一个数需要比较几次 10个数,第一轮需要跟9个数比较
// 第二轮只需跟8个数比较,以此类推
for (var j = 0; j < arrLength - i - 1; j++) {
// 从小到大排除
// 3. 当前一个数比后一个数大时,两个数交换
if (arr[i] > arr[j]) {
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
注意
外层循环的条件:i < arrLength - 1.。这个里面没有 = 。因为,最后一个数不需要再循环确定位置,其他数都归位了,最后一个数自然而然的就自动归为了。
快速排序
快排的核心思想:利用二分的思想进行比较交换实现排序。每一轮确定一组比基准大和比基准小的数交换。
快排的思想
通常,都把一组数的一个数作为基准数。
1.从数组右边找比基准数小的数,若比基准数大,右边的哨兵向左移动一个位置;
只有当找到一个比基准数小的数时,本次循环才会停止,也就是right哨兵停止位置
2.从数组的左边找比基准大的数,若比基准数小,左边的哨兵 i 向右移动一个位置;
只有当找到一个比基准大的数时,跳出循环,i停止位置
3.循环结束时,i的位置的数是比基准数大的数,j的位置的数是比基准数小的数, i 和 j 对应的数进行交换
4.当i与j相遇, 右哨兵找到了一个比基准数小的数,左哨兵没有找到比基准数大的数,直到遇到右哨兵.
此时,交换要把基准数与i对应的位置的数,进行交换 .完成第一轮的交换
5. 基准数此时再中间,重复上面1 2 3 4的步骤对基准左边的一组数和基准右边的一组数排序。
// 快排
function quickSort(arr, left, right) {
var i = left; // 指向数组第一个数
var j = right; // 指向数组的最后一个数
if (i >= j) {
return;
}
// 只有当 左边下标小于右边下标时,才进入循环
while (i < j) {
// 1. 右边的哨兵先出动 寻找一个比基准数小的数
while (i < j && arr[j] > arr[left]) { // 数比基准数大 就继续向左寻找
j--;
}
// 2. 左边哨兵出动 找比基准数大的
while (i < j && arr[i] < arr[right]) { // 数比基准数小 就继续向右找
i++;
}
// 3. 当左边哨兵找到比基准大的数 右边哨兵比基准小的数 两个数交换位置
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// 循环结束:i=j
// 重点:循环结束后,此时的arr[i]==arr[j] 是一个比基准数小的数
// 4.交换:基准数---arr[i]或者arr[j]
temp = arr[i];
arr[i] = arr[left];
arr[left] = temp;
// 交换后的数组,基准数在中间,基准数左侧的都是比基准数小的数,基准数右侧的都是基准数大的数
// 接着,按照同样的思路,把基准数左边一组数排序,右边一组数排序
// 此时, 左边一组数, 下标是 left - (i - 1)
// 右边的数组, 下标是(i + 1) - right
quickSort(arr, left, i - 1);
quickSort(arr, i - 1, right);
}
注意
先进入循环时,首先是右边的哨兵出动,因为要确保跳出循环时,arr[ j ]是一个比基准数小的数,这样才能在循环结束后,把arr[ j ]与基准数交换,再进行排序。