几种常见的排序算法(js)

几种常见的算法:

前端面视常问的几种排序算法:冒泡,选择,插入,快排,二分搜索;除此之外还有归并排序,堆排序等,本文主要对前五种常见的排序算法进行详解。

1.冒泡排序

最简单的一种排序算法。假设长度为n的数组arr,要按照从小到大排序。则冒泡排序的逻辑为:对数组进行遍历将最大的元素冒泡到最后,然后对剩下的n-1个数再次进行冒泡,一直循环下去直到所有数冒泡结束。
冒泡排序两层循环,时间复杂度为O(n^2)
代码如下:

function Bubble(nums){
  for(let i=0;i<nums.length;i++){
    for(let j=0;j<nums.length-1-i;j++){
      if(nums[j]>nums[j+1]){
        var temp = nums[j]
        nums[j] = nums[j+1]
        nums[j+1] = temp
      }
    }
  }
}

2.选择排序

假设长度为n的数组arr,要按照从小到大排序。对选择排序的基本思想描述为:从数组中选择最大的数与最后一位做交换,然后对剩下的n-1个数进行选择和交换,一直重复选择和交换,直到所有数字交换结束。
选择排序两层循环,时间复杂度为O(n^2)
代码如下:

function selectSort(arr) {
    if (arr.length < 2) return arr;
    for (let i = arr.length - 1; i > 0; i--) {
        var maxIndex = 0;
        for (let j = 0; j <= i; j++) {
            if(arr[j]>arr[maxIndex]){
                maxIndex = j;
            }
        }
        [arr[i],arr[maxIndex]] = [arr[maxIndex],arr[i]];
    }
    return arr;
}

3.插入排序

插入排序的基本思想就是将无序序列插入到有序序列中。它也是通过冒泡的形式将未排序的数冒泡到有序序列的正确位置。
插入排序两层循环,时间复杂度为O(n^2)
代码如下:

function Insert (arr) {
  if (arr.length < 2) return arr;
  for(let i=1;i<arr.length;i++){
    var target = i
    for(let j=i-1;j>=0;j--){
      if(arr[target]<arr[j]){
        [arr[target],arr[j]] = [arr[j],arr[target]]
        target = j
      }else{
        break
      }
    }
  }
}

4.快速排序

算法思想:快速排序的基本思想是基于分治法的。分治法是什么呢?就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。
算法描述:从待排序数组中选择一个元素作为轴点元素,然后将大于轴点元素的值放在轴点右边,小于轴点元素的值放在轴点左边;然后在对轴点左边序列进行快速排序,对轴点右边序列进行排序,重复以上步骤,直到待排序列中只有一个元素,停止排序。
快速排序算法时间复杂度为:O(nlogn)
快速排序的实质是逐渐使每个元素都成为轴点元素
代码如下:

function QuickSort(arr) {
  if(arr.length<2) return arr
  var pivotIndex = Math.floor(arr.length/2)
  var pivot = arr.splice(pivotIndex,1)[0] //取出轴点元素
  var left = [] ,rigth = []
  // 对数组左右分类(大于轴点元素的值放在轴点右边,小于轴点元素的值放在轴点左边)
  for(let i = 0;i < arr.length ;i++){
    arr[i] > pivot ? rigth.push(arr[i]) : left.push(arr[i])
  }
  // 对左右两部分进行快排,合并
  return QuickSort(left).concat([pivot],QuickSort(right))
}

5.二分搜索

算法思想:二分搜索是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。
折半搜索每次把搜索区域减少一半,时间复杂度为O(logn)
(递归版)代码如下:

function indexof(start, end, num) {
    var mid = parseInt((start + end) / 2);
    if (arr[mid] == num) {
        return mid;
    } else if (arr[mid] > num) {
        return indexof(start, mid, num);
    } else {
        return indexof(mid, end, num);
    }
}

(非递归)代码如下:

function midSearch(num) {
    var start = 0;
    var end = arr.length - 1;
    var mid = 0;
    if (num < arr[start] || num > arr[end]) {
        return -1;
    }
    while (start <= end) {
        mid = parseInt((start + end) / 2)
        if (num == arr[mid]) {
            return mid;
        }
        if (num < arr[mid]) {
            end = mid - 1;
        }
        if (num > arr[mid]) {
            start = mid + 1;
        }
    }
    return -1;
}

你可能感兴趣的:(算法,算法,排序算法)