1. 冒泡排序:O(n²)
前一项和后一项进行比较,一轮循环后,将最大的数放置在数组末尾,并使计算的数组长度减一,减少一次比较,然后进入下一轮循环
let arr = [3,64,43,7,74,10];
let len = arr.length;
for(let i = 0; i < len - 1; i++) { // n个数比较n-1次
for(let j = 0; j < len - 1 - i; j++) { // 每次有一个数被被确定,确定的数的量就是i,不用比较
if(arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
console.log(arr);
2. 选择排序:O(n²)
let arr = [3,64,43,7,74,10];
let len = arr.length;
let temp;
for(let i = 0; i < len - 1; i++) {
for(let j = 0; j < len; j++) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
3. 插入排序:O(n²)
let arr = [3,64,43,7,74,10];
let len = arr.length;
1.第一种方式
for (let i = 1; i < len; i++) {
for (let j = i; j > 0; j--) {
if (arr[j] < arr[j - 1]) {
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
}
2.第二种方式: 优化的插入排序,减少数组的访问次数
let preIndex;
for(let i = 1; i < len; i++) {
preIndex = i - 1;
current = arr[i]; //将当前项先存储
while(preIndex >= 0 && arr[preIndex] > current) { //使当前项与前一项进行比较
arr[preIndex + 1] = arr[preIndex]; //如果前面的项大于当前项就使前一项的索引加1
preIndex--; //然后再使当前项(保留值current)与前一项比较,直到小于当前项,退出循环
}
arr[preIndex + 1] = current; //此时的preIndex为比当前项小的项,所以将当前项插入到它的后面
}
console.log(arr);
4. 希尔排序:O(n^1.3)
let arr = [3,64,43,7,74,10];
let len = arr.length,
temp,
gap = Math.floor(len / 2), //将数组划分,可以自己选,但是一定要小于len
multiPreIndex;
while(gap > 0) {
for (let i = gap; i < len; i++) {
temp = arr[i]; //与插入排序一样,保留当前值
for (multiPreIndex = i - gap; multiPreIndex > 0 && arr[multiPreIndex]> temp; multiPreIndex -= gap) {
arr[multiPreIndex + gap] = arr[multiPreIndex]; //如果前面的那个项大于当前项,就将前面的项索引往后移gap个单位
}
arr[multiPreIndex + gap] = temp; //将当前值插入到比它小的项后面gap个单位索引的地方
}
gap = parseInt(gap / 2); //因为JS的数值都是浮点数,需要使用parseInt将其转化为整数,或者使用Math.floor,每次缩小范围
}
console.log(arr);
5. 归并排序:O(nlog2^n)
let arr = [3,67,43,7,74,10];
function mergeSort(arr) {
let len = arr.length;
if (len < 2) {
return arr;
}
let middle = parseInt(len / 2), //取中间值
left = arr.slice(0, middle), //取中间值前面的数
right = arr.slice(middle); //取中间值后面的数,包括中间值
return merge(mergeSort(left), mergeSort(right));
}
function merge(left, right) {
var result = [];
while (left.length > 0 && right.length > 0) {
if (left[0] <= right[0]) { //对两个数组的首项进行比较
result.push(left.shift()); //将小的首项添加到result数组,并且删除原数组该首项
} else {
result.push(right.shift());
}
}
while (left.length)
result.push(left.shift()); //将剩下的未比较项全部添加入result数组
while (right.length)
result.push(right.shift());
return result;
}
let array = mergeSort(arr);
console.log(array);
6. 快速排序:O(nlog2^n)
let arr = [3,67,43,7,74,10];
let array = quickSort(arr);
console.log(array);
function quickSort(arr, left, right) {
var len = arr.length,
partitionIndex,
left = typeof left != 'number' ? 0 : left,
right = typeof right != 'number' ? len - 1 : right;
if (left < right) {
partitionIndex = partition(arr, left, right); //返回基准,基准的左边都是比基准小的,右边都是比基准大的
quickSort(arr, left, partitionIndex - 1); //缩小范围,创建新的基准,进行比较
quickSort(arr, partitionIndex + 1, right);
}
return arr;
}
function partition(arr, left, right) {
var pivot = left, //将最左边(除去已经排好的)的数作为基准
index = pivot + 1; //
for (var i = index; i <= right; i++) {
if (arr[i] < arr[pivot]) { //基准右边的值与基准进行比较
swap(arr, i, index); //将比基准小的值放左边,比基准大的值放右边(都在基准后面)
index++; //index可以作为比基准小的数的个数
}
}
swap(arr, pivot, index - 1); //将基准插入到比它小的最右边数的后面
return index - 1;
}
function swap(arr, i, j) {
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
7. 堆排序:O(nlog2^n)
let arr = [3,67,43,7,74,10];
let len = arr.length;
let array = heapSort(arr);
console.log(array);
function buildMaxHeap(arr) { // 建立大顶堆
len = arr.length;
for (var i = Math.floor((len - 2) / 2); i >= 0; i--) { // len-2 防止超出数组长度
heapify(arr, i);
}
}
function heapify(arr, i) { // 堆调整
var left = 2 * i + 1, // 左结点,如第一个左节点的索引为1,层次i为0, 2 * 0 + 1 = 1
right = 2 * i + 2,
largest = i; // 把根结点i先当做最大值
if (left < len && arr[left] > arr[largest]) { //如果左结点存在且大于根结点
largest = left; //将左结点的索引赋值给根结点索引保存值
}
if (right < len && arr[right] > arr[largest]) {
largest = right;
}
if (largest != i) { //如果根结点索引保存值被赋值了新的值
swap(arr, i, largest); //就将新的索引和原根结点索引上的值互换
heapify(arr, largest);
}
}
function swap(arr, i, j) {
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
function heapSort(arr) {
buildMaxHeap(arr);
for (var i = arr.length - 1; i > 0; i--) {
swap(arr, 0, i); //将顶点(确定的最大值)和数组最后一个互换
len--; //使接下去的计算数组计算长度减一(不是原数组长度减一)
heapify(arr, 0); //因为最后一个数被放到最前面,不确定这个数和后面两个数的大小关系,因为没它们之间进行结点比较运算,所以需要再对前3项进行根结点和子节点的比较排序,后面的数之前已经按结点进行过比较
}
return arr;
}