javascript常见的排序方法

冒泡排序(O(n2))

冒泡排序比较任何两个相邻的项,如果第一个比第二个大,则交换它们。元素项向上移动至 正确的顺序,就好像气泡升至表面一样,冒泡排序因此得名。

function bubbleSort(list) {
  let length = list.length;
  for (let i = 0; i < length; i++) {
    // 从内循环减去外循环中已跑过的轮数,就可以避免内循环中所有不必要的比较
    for (let j = 0; j < length - 1 + i; j++) {
      if (list[j] < list[j + 1]) {
      	// es6交换元素
        [list[j + 1], list[j]] = [list[j], list[j + 1]];
      }
    }
  }
  return list;
}
console.log(bubbleSort([5,4,3,2,1]))

选择排序(O(n2))

选择排序大致的思路是找到数据结构中的最小值并 将其放置在第一位,接着找到第二小的值并将其放在第二位,以此类推。

function selectionSort(list) {
  let length = list.length, 
    indexMin;
  for (var i = 0; i < length - 1; i++) {
  	// 假设当前的i为数组的最小值
    indexMin = i; 
    for (var j = i + 1; j < length; j++) {
      // 如果j的值比indexMin的值小,则把j赋值给indexMin
      if (list[indexMin] > list[j]) {
        indexMin = j;
      }
    }
    // 不相等则交换元素
    if (i !== indexMin) {
      // es6交换元素
      [list[i], list[indexMin]] = [list[indexMin], list[i]];
    }
  }
  return list;
}

插入排序(O(n2))

插入排序每次排一个数组项,以此方式构建最后的排序数组。假定第一项已经排序了,接着, 用第二项和第一项想比较,是插入到第一项之前,还是之后,然后用第三项,去和之前的第一、第二项比较,找出插入的位置,以此类推

function insertionSort(array) {
  var length = array.length,
    j,
    temp;
  // 注意i不是从0开始的,我们认为第一项已经排序
  for (let i = 1; i < length; i++) {
    // 初始位置为i
    j = i;
    // 采用临时变量存起来
    temp = array[i];
    // 用于找到temp需要插入的位置j
    while (j > 0 && array[j - 1] > temp) {
      array[j] = array[j - 1];
      j--;
    }
    // 插入
    array[j] = temp;
  }
  return array;
}

归并排序(O(nlogn))

归并排序是一种分治算法(采用递归实现)。其思想是将原始数组切分成较小的数组,直到每个小数组只有一 个位置,接着将小数组归并成较大的数组,直到最后只有一个排序完毕的大数组。Firefox的Array.prototype.sort的实现就是归并排序

function merge(left, right) {
  let result = [],
    il = 0,
    ir = 0;
  while (il < left.length && ir < right.length) {
    if (left[il] < right[ir]) {
      result.push(left[il++]);
    } else {
      result.push(right[ir++]);
    }
  }
  while (il < left.length) {
    result.push(left[il++]);
  }
  while (ir < right.length) {
    result.push(right[ir++]);
  }
  return result;
}

function mergeSortRec(array) {
  let length = array.length;
  if (length === 1) {
    return array;
  }
  let mid = Math.floor(length / 2);
  let left = array.slice(0, mid);
  let right = array.slice(mid);
  return merge(mergeSortRec(left), mergeSortRec(right));
}

function mergeSort(array) {
  return mergeSortRec(array);
}

快速排序(O(nlogn))

最常用的排序算法,也是分治算法。Chrome的Array.prototype.sort的实现就是快速排序

  • 首先,从数组中选择中间一项作为对比项pivot。

  • 创建两个指针,左边一个指向数组第一个项,右边一个指向数组最后一个项。移动左指 针直到我们找到一个比pivot的元素,接着,移动右指针直到找到一个比pivot小的元素,然后交 换它们,重复这个过程,直到左指针超过了右指针。这个过程将使得比pivot小的值都排在pivot之前,而比pivot大的值都排在pivot之后。最后返回左指针位置,继续划分

  • 接着,对划分后的小数组(左边比pivot小的值组成的子数组,以及较pivot大的值组成的子数组)重复之前的两个步骤,直至数组已完全排序。

function partition(array, left, right) {
  let pivot = array[Math.floor((left + right) / 2)],
    i = left,
    j = right;

  while (i <= j) {
    while (array[i] < pivot) {
      i++;
    }
    while (array[j] > pivot) {
      j--;
    }

    if (i <= j) {
      [array[i], array[j]] = [array[j], array[i]];
      i++;
      j--;
    }
  }
  return i;
}

function quick(array, left, right) {
  let index;
  if (array.length > 1) {
    index = partition(array, left, right);
    if (left < index - 1) {
      quick(array, left, index - 1);
    }
    if (index < right) {
      quick(array, index, right);
    }
  }
}

function quickSort(array) {
  quick(array, 0, array.length - 1);
  console.log(array);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值