【JavaScript 算法】- 冒泡排序 / 插入排序 / 选择排序

111 阅读2分钟

前言

排序算法可以说是最常见的算法之一了,而我们分析一个排序算法,需要从 执行效率 内存消耗 稳定性这三个方面来入手。

  1. 执行效率

    执行代码的时间复杂度,同时比较数据的交换或者移动的次数

  2. 内存消耗

    即空间复杂度

  3. 稳定性

    稳定的表现是如果待排序的序列中存在值相等的元素,经过排序之后,相等元素之间原有的先后顺序不变。不稳定即经过排序之后,相等元素之间原有的先后顺序改变。

冒泡排序

思路

每次操作只会操作两个相邻的元素,冒泡操作就是对相邻的两个元素进行比较,对比大小关系来决定两个元素是否要互换位置。

一次冒泡至少会让一个元素移动到它应该在的位置,重复 n 次就完成了 n 个数据的排序工作。

特点

优点是简单实用易于理解,缺点就是比较次数比较多,效率比较低

实现

const bubbleSort = arr => {
    // 从大到小排列
    const length = arr.length;
    // 首先考虑数组长度只有一个或者为 0 的情况
    if (length <= 1) {
        return arr;
    }
    for (let i = 0; i <= length - 1; i++) {
        // 最外层只需要循环一个数组的长度,所以到最后一个索引就可以了
        // 里面的循环比外层少一个,且比较的值是当前值的后一个,所以是
        for (let j = i + 1; j <= length - 1; j++) {
            if (arr[i] < arr[j]) {
                const temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
    }
    return arr;
}

插入排序

插入排序又为分为 直接插入排序 和优化后的 拆半插入排序希尔排序,我们通常说的插入排序是指 直接插入排序

思路

一般人打扑克牌,整理牌的时候,都是按牌的大小(从小到大或者从大到小)整理牌的,那每摸一张新牌,就扫描自己的牌,把新牌插入到相应的位置。

插入排序的工作原理:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

步骤:

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

实现

const insertionSort = (array) => {
  const len = array.length;
  if (len <= 1) return;

  let preIndex, current;
  for (let i = 1; i < len; i++) {
    preIndex = i - 1; // 待比较元素的下标
    current = array[i]; // 当前元素
    while (preIndex >= 0 && array[preIndex] > current) {
      // 前置条件之一:待比较元素比当前元素大
      array[preIndex + 1] = array[preIndex]; // 将待比较的元素后移一位
      preIndex--; // 游标前移一位
    }
    if (preIndex + 1 != i) {
      // 避免同一个元素赋值给自身
      array[preIndex + 1] = current; //将当前元素插入预留空位
      console.log('array:', array);
    }
  }
  return array;
};

测试~

选择排序

选择排序算法的实现思路有点类似插入排序,也分已排序区间和未排序区间。但是选择排序每次会从未排序区间中找到最小的元素,将其放到已排序区间的末尾。

思路

步骤:

  1. 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
  2. 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
  3. 重复第二步,直到所有元素均排序完毕。

实现

const selectionSort = array => {
	const len = array.length;
	let minIndex, temp;
	for (let i = 0; i < len - 1; i++) {
		minIndex = i;
		for (let j = i + 1; j < len; j++) {
			if (array[j] < array[minIndex]) {
				// 寻找最小的数
				minIndex = j; // 将最小数的索引保存
			}
		}
		temp = array[i];
		array[i] = array[minIndex];
		array[minIndex] = temp;
		console.log('array: ', array);
	}
	return array;
};

总结

排序算法的复杂性对比

算法可视化工具:algorithm-visualizer 是一个交互式的在线平台,可以从代码中可视化算法,还可以看到代码执行的过程。