几种排序算法

1.冒泡排序

function bubbleSort(arr){
  for(var i =0 ;i < arr.length; i++){
    for(var j = i+1; j < arr.length - 1; j++){
      if(arr[i] > arr[j]){
        var temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
      }
    }
  }
  return arr;
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(bubbleSort(arr));

改进冒泡排序: 设置一标志性变量pos,用于记录每趟排序中最后一次进行交换的位置。由于pos位置之后的记录均已交换到位,故在进行下一趟排序时只要扫描到pos位置即可。

function bubbleSort(arr){
  var i = arr.length-1;
  while(i>0){
    var pos = 0;
    for(var j = 0; j < i; j++){
      if(arr[j] > arr[j+1]){
        pos = j;
        var temp = arr[j];
        arr[j] = arr[j+1];
        arr[j+1] = temp;
      }
    }
    i = pos;
  }
  return arr;
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(bubbleSort(arr));

传统冒泡排序中每一趟排序操作只能找到一个最大值或最小值,我们考虑利用在每趟排序中进行正向和反向两遍冒泡的方法一次可以得到两个最终值(最大者和最小者) , 从而使排序趟数几乎减少了一半。

function bubbleSort(arr){
  var low = 0,
      hight = arr.length - 1;
  var tmp,j;
  while(low < hight){
    for(j = low; j < hight; ++j){
      if(arr[j] > arr[j+1]){
        tmp = arr[j];
        arr[j] = arr[j+1];
        arr[j+1] = tmp;
      }
    }
    --hight;
    for(j = hight; j > low; --j){
      if(arr[j] < arr[j-1]){
        tmp = arr[j];
        arr[j] = arr[j-1];
        arr[j-1] = tmp;
      }
    }
    ++low;
  }
  return arr;
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(bubbleSort(arr));

算法分析

  • 最佳情况:T(n) = O(n)
    当输入的数据已经是正序时
  • 最差情况:T(n) = O(n^2)
    当输入的数据是反序时
  • 平均情况:T(n) = O(n^2)

2.选择排序

(1)算法简介

选择排序(Selection-sort)是一种简单直观的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

(2)算法描述和实现

n个记录的直接选择排序可经过n-1趟直接选择排序得到有序结果。具体算法描述如下:

<1>.初始状态:无序区为R[1..n],有序区为空;
<2>.第i趟排序(i=1,2,3…n-1)开始时,当前有序区和无序区分别为R[1..i-1]和R(i..n)。该趟排序从当前无序区中-选出关键字最小的记录 R[k],将它与无序区的第1个记录R交换,使R[1..i]和R[i+1..n)分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区;
<3>.n-1趟结束,数组有序化了。

function selectionSort(arr){
  var len = arr.length;
  var tmp,minIndex;
  for(var i = 0; i < len - 1; i++){
    minIndex = i;
    for(var j = i + 1;j < len ;j++){
      if(arr[j] < arr[minIndex]){
        minIndex = j;
      }
    }
    tmp = arr[i];;
    arr[i] = arr[minIndex];
    arr[minIndex] = tmp;
  }
  return arr;
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(selectionSort(arr));

(3)算法分析

  • 最佳情况:T(n) = O(n^2)
  • 最差情况:T(n) = O(n^2)
  • 平均情况:T(n) = O(n^2)

3.插入排序

(1)算法简介

插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

(2)算法描述和实现

一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下:

<1>.从第一个元素开始,该元素可以认为已经被排序;
<2>.取出下一个元素,在已经排序的元素序列中从后向前扫描;
<3>.如果该元素(已排序)大于新元素,将该元素移到下一位置;
<4>.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
<5>.将新元素插入到该位置后;
<6>.重复步骤2~5。

function insertionSort(arr){
  for(var i = 1; i < arr.length; i ++){
    var k = arr[i];
    var j = i - 1; 
    while(j >= 0 && arr[j] > k){
      arr[j+1] = arr[j];
      j--;
    }
    arr[j+1] = k;
  }
  return arr;
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log( insertionSort(arr));

改进插入排序: 查找插入位置时使用二分查找的方式

function sort(arr){
  for(var i = 1; i < arr.length; i ++){
    var k = arr[i];
    var left = 0,
        right = i - 1;
    while(left <= right){
      var middle = parseInt((right + left) / 2);
      if(k < arr[middle]){
        right = middle - 1;
      }else{
        left = middle + 1;
      }
    }
    for(var j = i - 1;j >= left; j--){
      arr[j+1] = arr[j];
    }
    arr[left] = k;
  }
  return arr;
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(sort(arr));

(3)算法分析

  • 最佳情况:输入数组按升序排列。T(n) = O(n)
  • 最坏情况:输入数组按降序排列。T(n) = O(n^2)
  • 平均情况:T(n) = O(n^2)

4.归并排序

(1)算法简介

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。归并排序是一种稳定的排序方法。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。

(2)算法描述和实现

具体算法描述如下:

<1>.把长度为n的输入序列分成两个长度为n/2的子序列;
<2>.对这两个子序列分别采用归并排序;
<3>.将两个排序好的子序列合并成一个最终的排序序列。

function mergeSort(arr){
  var len = arr.length;
  if(len < 2){
    return arr;
  }
  var middle = Math.floor(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 && right.length){
    if(left[0] <= right[0]){
      result.push(left.shift());
    }else{
      result.push(right.shift());
    }
  }
  while(left.length){
    result.push(left.shift());
  }
  while(right.length){
    result.push(right.shift());
  }
  return result;
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(mergeSort(arr));

(3)算法分析

  • 最佳情况:T(n) = O(n)
  • 最差情况:T(n) = O(nlogn)
  • 平均情况:T(n) = O(nlogn)

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