【路飞】排序算法01

224 阅读3分钟

排序算法(一)

记录自己的学习-

以升序来写

冒泡算法

贴张图

下载.gif

比较相邻的元素,通过大小对比调换位置 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。针对所有的元素重复以上的步骤,除了最后一个。持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较

function bubbleSort(arr) {
    const len = arr.length
    for (let i = 0; i < len - 1) {
        // 遍历对比两个相邻元素大小 只需要到已经‘冒泡’位置(len - 1 -i)
        for (let j = 0; j < len - 1 - i) {
            if (arr[j] > arr[j + 1]) {
                [arr[j + 1], arr[j]] = [arr[j + 1], arr[j]]
            }
        }
    }
    return arr
}

选择排序

图来 selectionSort.gif

选择排序较为简单 两次遍历确定当前需要最小值, 通过比较 在找到未确定大小中的最小值 调换位置

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

function selectSort (arr) {
    const len = arr.length
    for(let i = 0; i < len - 1; i++) {
        let minIndex = i // 记录最小值下标
        for (let j = i + 1; j < len - 1; j++) {
            if (arr[minIndex] > arr[j]) {
                minIndex = j
            }
        }
        [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]]
    }
    
    return arr
}

插入排序

insertionSort.gif

通过对比前面的大小 进行插入

将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。 从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)

function insertSort(arr) {
    const len = arr.length
    for (let i = 0; i < len; i++) {
        let cur = i
        // 因为第一次比较 cur = 0 arr[cur - 1] 是 undefined js里小于 任何数 也可已不写 cur - 1 > 0 的判断
        while(cur - 1 >= 0 && arr[cur - 1] > arr[cur]) {
            [arr[cur - 1], arr[cur]] = [arr[cur], arr[cur - 1]]
            cur--
        }
    }
    return arr
}

希尔排序

图来

849589-20180331170017421-364506073.gif

通过‘分组’ 划分数组 把每个分组进行插入排序 有点是每次分组后的插入排序调换位置次数会变少

function shellSort(arr) {
  const len = arr.length
  let gap = Math.floor(len / 2)
  while (gap > 0) {
    for (let i = gap; i < len; i++) {
      // 把每个分组通过gap ’抽离‘ 出来 进行插入排序
      let j = i
      while (j - gap >= 0 && arr[j - gap] > arr[j]) {
        [arr[j], arr[j - gap]] = [arr[j - gap], arr[j]]
        j -= gap
      }
    }

    gap = Math.floor(gap / 2)
  }

  return arr
}

快速排序

quickSort.gif

通过一个基准点 划分left right 两个区域 一次对left right 两个区域进行递归

function partition(arr, left, right) {
  const pivot = left
  let index = pivot + 1
  for (let i = index; i <= right; i++) {
    if (arr[i] < arr[pivot]) {
      // 按照基准点arr[pivot] 进行分组 小于 移动到left 剩余的在right
      [arr[i], arr[index]] = [arr[index], arr[i]]
      // 确定新的基准点的位置
      index++
    }
  }
  // 变换新的基准点
  [arr[pivot], arr[index - 1]] = [arr[index - 1], arr[pivot]]
  return index - 1
}

function quickSort(arr, left, right) {
  const len = arr.length
  let partitionIndex
  left = typeof left != 'number' ? 0 : left
  right = typeof right != 'number' ? len - 1 : right

  if (left < right) {
    partitionIndex = partition(arr, left, right)
    quickSort(arr, left, partitionIndex - 1)
    quickSort(arr, partitionIndex + 1, right)
  }

  return arr
}

总结

记录学习的输出,跟羊村长一起daydyaup 算法 数据结构 思维 太差了,刚开始入门的就卡壳,但是成长是很大的 常规的冒泡,选择,插入可以比较轻松搞定,希尔排序和快排 虽然大致搞清楚,可以写出来,但总感觉过段时间会忘记了,哈哈哈 这次输出的文章有些应付了,但是相信通过不断的学习可以游刃有余 有想一起学习 可以@杨村长掘金地址