经典排序算法(1)

184 阅读3分钟
  1. 冒泡排序,比较相邻元素,如果第一个比第二个大就进行交换;最后一个元素是最大的;
var count = 0;
//循环的次数
for (let i = 0; i < arr.length - 1; i++) {
  //每一轮外层循环都会将当前最大的元素“冒泡”到数组的末尾,
  for (let j = 0; j < arr.length - i - 1; j++) {
    //所以内层循环中无需再对已经排序好的尾部元素进行比较
    if (arr[j] > arr[j + 1]) {
      //前一个比后一个大两两交换
      let temp = arr[j];
      arr[j] = arr[j + 1];
      arr[j + 1] = temp;
      //解构 [arr[j],arr[j+1]]=[arr[j+1],[arr[j]]]
      console.log("i=" + i, arr);
    }
  }
  count++;
}
console.log(arr + ",比较" + count + "轮"); //1,2,3,4,5

bubbleSort.gif

  1. 选择排序:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置
var count = 0;
for (let i = 0; i < arr.length - 1; i++) {
  let minIndex = i;
  for (let j = i + 1; j < arr.length; j++) {
    //只有当最小元素的索引 minIndex 不等于当前位置 i 时,才进行交换。
    if (arr[j] < arr[minIndex]) {
      minIndex = j;
    }
  }
  if (minIndex !== i) {
    let temp = arr[minIndex];
    arr[minIndex] = arr[i];
    arr[i] = temp;
    console.log("i=" + i, arr);
  }
  count++;
}
console.log(arr + ",比较" + count + "轮");

selectionSort.gif

  1. 插入排序: 将数组分为已排序部分和未排序部分,每次从未排序部分取出一个元素, 并将其插入到已排序部分的合适位置。
var count = 0;
for (var i = 0; i < arr.length - 1; i++) {
  // 注意 n--, 是为了从后向前比较
  for (var n = i; n >= 0; n--) {
    if (arr[n] > arr[n + 1]) {
      var temp = arr[n];
      arr[n] = arr[n + 1];
      arr[n + 1] = temp;
      console.log("i=" + i, arr);
    }
  }
  count++;
}
console.log(arr + ",比较" + count + "轮");

insertionSort.gif

  1. 快速排序:在数组中选数组一个元素作为‘基准’,将数组中小于基准的数据移到基准左边,大于基准的移到基准右边,不断重复,直到每个子集只有一个元素
  if (arr.length <= 1) {
    return arr;
  }
  var left = [];
  var right = [];
  var pivot = arr[0];
  for (let i = 1; i < arr.length; i++) {
    if (arr[i] < pivot) {
      left.push(arr[i]);
    } else {
      right.push(arr[i]);
    }
  }
  return quickSort(left).concat(pivot, quickSort(right));
}
var arr = [3, 1, 5, 2, 4, 1, 2, 2];
console.log("排序结束:", quickSort(arr)); //[1, 1, 2, 2, 2, 3, 4, 5]
console.log("原数组", arr); // [3, 1, 5, 2, 4, 1, 2, 2]

quickSort.gif

image.png

  1. 希尔排序:把记录按下表的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
function insertSort(data) {
  var gap = Math.floor(data.length / 2);
  var temp; //用于存储需要插入的数据
  //注意i从gap开始,因为以data[0]为基准数,j=i-1
  while (gap >= 1) {
    for (let i = gap; i < data.length; i++) {
      temp = data[i]; //将第i个数保存,以供之后插入合适位置使用
      // 因为前i-1个数都是从小到大的有序序列,只要当前比较的数(data[j-1])比temp大,就把这个数后移一位
      for (var j = i - gap; j >= 0 && data[j] > temp; j = j - gap) {
        //这块j得用var声明,因为在for循环之外的作用域还要用j
        data[j + gap] = data[j];
      }
      data[j + gap] = temp; //将temp插入合适的位置
    }
    gap = Math.floor(gap / 2);
  }
  return data;
}
var sortedData = insertSort(dat);
console.log(sortedData);

4099767-ef47c7066af198d3.gif

image.png