【算法】冒泡排序

冒泡排序的思路:遍历数组,然后将最大数沉到最底部;
「时间复杂度:O(N^2);」
「空间复杂度:O(1)」

 一、标准方式

// 冒牌排序算法
function bubbleSort(arr) {
  // 如果数组为空则直接返回空数组[]
  if (arr == null || arr.length <= 0) {
    return [];
  }
  // 定义变量
  const len = arr.length;
  // 第一层循环,从数组末尾到开头遍历
  for (let end = len - 1; end > 0; end--) {
    // 第二层循环,从数组开头到当前末尾遍历
    for (let i = 0; i < end; i++) {
      // 判断如果第一位大于下一位则交换两数的位置
      if (arr[i] > arr[i + 1]) {
        swap(arr, i, i + 1);
      }
    }
  }
  // 返回冒泡后的数组
  return arr
}

// 辅助函数,用于交换数组中的两个元素
function swap(arr, i, j) {
  const temp = arr[i];
  arr[i] = arr[j];
  arr[j] = temp;
}

这种方式采取了辅助函数和双层for循环的方式来进行冒泡排序的实现

如不想使用辅助函数可以优化为下面这种方式

function bubbleSort(arr) {
  // 如果数组为空则直接返回空数组[]
  if (arr == null || arr.length <= 0) {
    return [];
  }
  // 定义变量
  const len = arr.length;
  // 第一层循环,从数组末尾到开头遍历
  for (let end = len - 1; end > 0; end--) {
    // 第二层循环,从数组开头到当前末尾遍历
    for (let i = 0; i < end; i++) {
      // 判断如果第一位大于下一位则交换两数的位置
      if (arr[i] > arr[i + 1]) {
        //数组解构的方式交换两个数的位置
        [arr[i], arr[i + 1]] = [arr[i+1], arr[i]];
      }
    }
  }
  // 返回冒泡后的数组
  return arr
}

目前的实现是标准的冒泡排序算法,其时间复杂度为O(n^2)。这意味着对于较大的数组,算法的性能可能会受到影响。

二、优化

一种优化方法是添加一个标志来跟踪是否进行了交换。如果在一次遍历中没有进行任何交换,则可以确定数组已经排序完成,可以提前退出循环。这样可以减少不必要的比较和交换,从而提高算法的性能。

以下是优化后的 bubbleSort 函数的示例实现:

function bubbleSort(arr) {
  // 定义函数bubbleSort,接收一个数组作为参数
  if (arr == null || arr.length <= 0) {
    // 如果数组为空或长度为0,则返回一个空数组
    return [];
  }

  const len = arr.length; // 获取数组的长度
  let swapped = false; // 定义一个标志,用于记录是否进行了交换

  // 外层循环,从数组的最后一个元素开始,到第二个元素结束
  for (let end = len - 1; end > 0; end--) {
    swapped = false; // 每次循环开始前,将标志重置为false

    // 内层循环,从第一个元素开始,到当前外层循环的结束位置
    for (let i = 0; i < end; i++) {
      if (arr[i] > arr[i + 1]) {
        // 如果当前元素比下一个元素大,则交换它们的位置
        swap(arr, i, i + 1); // 调用swap函数,交换两个元素的位置
        // [arr[i], arr[i + 1]] = [arr[i+1],arr[i]];
        swapped = true; // 标志设置为true,表示进行了交换
      }
    }

    if (!swapped) {
      // 如果在一次遍历中没有进行任何交换,则说明数组已经排序完成,可以提前退出循环
      break;
    }
  }

  return arr; // 返回排序后的数组
}

// 辅助函数,用于交换数组中的两个元素
function swap(arr, i, j) {
  const temp = arr[i];
  arr[i] = arr[j];
  arr[j] = temp;
}

这个实现在每次遍历中都会检查是否进行了交换,并在没有交换的情况下提前退出循环。这样可以减少比较和交换的次数,从而提高算法的性能。

相比于原始的冒泡排序算法,这种优化方式可以减少不必要的比较和交换,从而提高算法的性能。在最坏情况下,即数组已经按照相反的顺序排列,优化后的算法的时间复杂度仍然是O(n^2),但是在其他情况下,算法的性能会得到显著的提升。

三、测试用例

以下是针对 bubbleSort 函数的测试用例:

// 测试用例1:正常情况下的排序
const arr1 = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5];
const sortedArr1 = bubbleSort(arr1);
console.log(sortedArr1);  // [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]

// 测试用例2:数组为空的情况
const arr2 = [];
const sortedArr2 = bubbleSort(arr2);
console.log(sortedArr2);  // []

// 测试用例3:数组只有一个元素的情况
const arr3 = [1];
const sortedArr3 = bubbleSort(arr3);
console.log(sortedArr3);  // [1]

// 测试用例4:数组已经按照相反的顺序排列的情况
const arr4 = [9, 8, 7, 6, 5, 4, 3, 2, 1];
const sortedArr4 = bubbleSort(arr4);
console.log(sortedArr4);  // [1, 2, 3, 4, 5, 6, 7, 8, 9]

你可能感兴趣的:(javascript算法,算法,排序算法,数据结构,javascript,前端)