js编写四种基础排序(冒泡排序、选择排序、插入排序、快速排序)

讲到算法,不可避免的会提到排序算法;在排序算法中,冒泡排序、选择排序和插入排序等是最常被问到的几种基本的排序算法。下面用js来实现这几个简单的排序。

1、冒泡排序

概念

从序列的最右边开始比较相邻两个数字的大小,再根据结果交换两个数字的位置,重复这一操作,实现所有数字从小到大或从大到小排列的算法即冒泡排序。

步骤

  1. 外层循环,n长的数组需要比较n趟,每次找到一个最小值
  2. 内层循环,每一趟之后需要比较的个数减1;
  3. 从序列的末尾开始比较相邻两个数字的大小;如果比较的数据比左边相邻的数据小,则左移当前比较的数据。
  4. 直至当前比较数据的位置等于当前比较次数时,则一轮结束。
  5. 比较完一轮后,继续从末尾开始比较下一轮

代码

// 编写方法,实现冒泡
var arr = [29,45,29,72,51,68,72,97];
var getMaopao = function(arr) {
  //外层循环,控制趟数,每一次找到一个最小值
  for (var i =0; i< arr.length - 1; i++){
    // 内层循环,从右侧开始控制比较的次数,并且判断两个数的大小
    for (var j = arr.length; j>= i; j--){
      // 如果后面的数小,放到前面(从小到大的冒泡排序)
      if (arr[j]< arr[j-1]) {
        var temp = arr [j];
        arr [j] = arr[j-1];
        arr[j-1] = temp;
      }
    }
  }
  return arr;
}
console.log('maopao', getMaopao(arr))

也可以是从前到后比较

for (var i = 0; i < arr.length - 1; i++) {
    // 内层循环,控制比较的次数,并且判断两个数的大小
    for (var j = 0; j < arr.length - 1 - i; j++) {
        if (arr[j] > arr[j + 1]) {
            var temp = arr[j];
            arr[j] = arr[j + 1];
            arr[j + 1] = temp;
        }
    }
}

2、选择排序

概念

从待排序的数据中寻找最小值,将其与序列最左边的数字进行交换,重复这一操作的算法即选择排序。

步骤

  1. 循环数组,找到最小值
  2. 将最小值和最左边的元素进行调换,完成第一轮
  3. 从第二位开始,循环数组,找到剩下的最小值
  4. 重复直到最后一轮,依次完成所有数据的排序

代码

var arr = [120,29,45,29,72,51,68,72,97];
var getChoose = function(arr) {
  //外层循环,控制趟数,每一次找到一个最小值
  for (var i =0; i< arr.length - 1; i++){
    // 内层循环,从右侧开始控制比较的次数,并且判断两个数的大小
    var min = arr[i];
    var minIndex = i;
    // 内层循环,每一次找到余下数字的最小值,记录下标
    for (var j = i; j< arr.length; j++){
      if (arr[j]<min) {
        min = arr[j]
        minIndex = j
      }
    }
    // 将最小值与第i位交换位置
    var temp = arr[i]
    arr[i] = arr [minIndex]
    arr[minIndex] = temp
  }
  return arr;
}
console.log('choose', getChoose(arr))

如果不记录下标,在内层循环交换位置也是可以的(每次都把最小值往前交换,类似冒泡),但是这样交换的次数会很多,运行速度会变慢。

3、插入排序

概念

从序列左端开始依次对数据进行排序的算法称为插入排序。(序列中数据分为已排序区和未排序区,依次对每个数据和已排序区比较,进行排序)

步骤

  1. 假设第一个数字已完成排序,对第二个数字与第一个进行比较
  2. 如果小于它,则放到它之前,否则之后,完成排序
  3. 然后第三个数字,与前两个已排序的进行比较,找到小于它的数字,放在此数字之后
  4. 如此反复,完成整个数组的排序

代码

// 编写方法,实现插入排序
var arr = [120,29,45,29,72,51,68,72,97];
var getChoose = function(arr) {
  var newArr = [arr[0]];
  //外层循环旧数组,获得未排序区的数字
  for (var i =1; i< arr.length; i++){
    // 内层循环新数组,将未排序区的数字与已排序区比较
    for (var j = 0; j< newArr.length; j++) {
      // 当数字小于已排序区的某个数字时,将此数字插入在已排序区的该数字之后,跳出循环
      if (arr[i]< newArr[j]) {
        newArr.splice(j,0,arr[i])
        break;
      }
    }
  }
  return newArr;
}
console.log('choose', getChoose(arr))

4、快速排序

概念

快速排序的原理,简单来说就是把一个事情,分成很多小事情来处理,分治的思想。如找到一个基准,将大于它的放到右边,小于它的所有数放到左边,再分别对左右的数组重复此步骤,最后数组将按照从小到大的顺序排列。

步骤

  1. 找基准(一般是以第一项为基准)
  2. 遍历数组,小于基准的放在left,大于基准的放在right
  3. 递归,对left和right内的数组不断重复以上方式,直到最后剩下一位。(有些二分法的意思)

代码

let dat=[5, 8, 10, 3, 2, 18, 17, 9];
var sortedData=function quickSort(data){
  //递归出口
    if(data.length<=1){
      return data;
  }
//此处要将基准数从原数组移除,避免上面的data.length判断陷入死循环
  let  baseData=data.splice(0,1)[0];
  let  leftData=[],rightData=[];
//此处的data.length和上面不同,移除了基准数,比上面小1
   for(let i=0;i<data.length;i++){
      if(data[i]>baseData){
        rightData.push(data[i]);
      }else{
        leftData.push(data[i]);
      }
    }
    leftData=quickSort(leftData);
    rightData=quickSort(rightData);
    return   [...leftData, baseData, ...rightData];
  }
console.log(sortedData(dat));
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章