数组6大排序算法

news2024/10/7 4:24:02

快速排序

核心算法:

1.取一个基准值(一般是数组中间的元素),遍历数组,比基准值大的放右边,小的放左边,相等的则不动

2.分别创建三个数组来存储元素,最后将三个数组拼接起来

3.循环调用函数,存储相等值的数组不变,其余两个数组作为函数参数

function quicksort(arr) {
  if (arr.length <= 1) return arr
  let baseValue = arr[Math.floor(arr.length / 2)]
  let commonArr = []
  let bigArr = []
  let smallArr = []
  arr.forEach(item => {
    if (item === baseValue) {
      commonArr.push(item)
    } else if (item > baseValue) {
      bigArr.push(item)
    } else {
      smallArr.push(item)
    }
  })
  return quicksort(smallArr).concat(commonArr, quicksort(bigArr))
  // 也可以写成:
  // return [...quicksort(smallArr),...commonArr,...quicksort(bigArr)]
}

冒泡排序

核心算法:

1.循环遍历数组元素

2.挨在一起的两个元素进行比较,大的放后面,这样遍历一次数组后,最大的元素将放在最后面

function bubblesort(arr) {
  const newArr = [...arr]
	// i用于控制多少轮
  for (let i = 0; i < newArr.length - 1; i++) {
    for (let j = 0; j < newArr.length - 1 - i; j++) {
      // 当前值大于后面的值,则对调位置
      newArr[j] > newArr[j + 1] && ([newArr[j], newArr[j + 1]] = [newArr[j + 1], newArr[j]])
    }
  }
  return newArr
}

选择排序

核心算法:

1.循环遍历每一个元素

2.每次选择一个元素,和后面的元素比较大小,如果后面的元素更小,则交换值。

function selectSort(arr) {
  // 这层循环用于控制遍历的次数
  for (let i = 0; i < arr.length; i++) {
    // minIndex用来记录最小值所对应的索引
    let minIndex = i
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[minIndex] > arr[j]) minIndex = j
    }
    // 如果找到更小的值,则调换位置
    if (minIndex !== i) [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]]
  }
  return arr
}

插入排序

思想一:

核心算法(类似于打牌,最终手上的牌按从小到大的顺序排好):

1.先抽出一张牌放到手上,方便后续比较

2.每次抽出一张牌,都要和手上的牌进行比较,插到合适的位置。

3.如果比手上的某一张牌大,则插入到这张牌的后面;如果比较一轮后,没有找到合适的位置,则说明它是最小的,放到最前面

function insertSort(arr) {
  let newArr = []
  // 手里先拿一张牌
  newArr.push(arr[0])
  for (let i = 1; i < arr.length; i++) {
    const A = arr[i]
    // 抽出一张牌,从大到小和手里的牌进行比较
    for (let j = newArr.length - 1; j >= 0; j--) {
      const B = newArr[j]
      // 比某一张牌大,则插入到这张牌的后面
      if (A >= B) {
        newArr.splice(j + 1, 0, A)
        break
      }
      // 如果比较一轮后,不满足前面的条件,说明这张牌是最小的,则放到最前面
      if (j === 0) newArr.unshift(A)
    }
  }
  return newArr
}

思想二:

核心算法:

1.默认数组中的第一个元素为有序数组

2.依次遍历无序数组,每次取一个元素和有序数组中所有元素作比较,如果某个元素比它大,则后移一位

function insertSort(arr) {
  // 认为第一个元素是有序的,所以不用遍历
  for (let i = 1; i < arr.length; i++) {
    let key = arr[i]
    let j = i - 1
    // 拿一个数和有序数组中的所有元素作比较
    for (; j >= 0 && arr[j] > key; j--) { 
      // 如果元素比这个数大,则元素向后移动
      arr[j+1] = arr[j]
    }
    // 这个数被插到合适的位置
    arr[j+1] = key
  }
  return arr
}

希尔排序

核心算法(相当于是插入排序的升级版,无非就是在外面多嵌套一层循环):

1.对相隔一定值的元素进行排序(刚开始一般是数组长度的一半),使数组相对有序

2.后面不断缩小这个值,直到为1(即最后会进行一次插入排序)

function shellSort(arr) {
  let len = arr.length
  let gap = Math.floor(len / 2)
  while (gap) {
    // 假设同组的第一个元素是有序的,遍历无序数组
    for (let i = gap; i < len; i++) {
      let key = arr[i]
      let j = i - gap
      // 用无序数组中的第一个元素依次和有序数组作比较
      for (; j >= 0 && key < arr[j]; j -= gap) {
        // 如果比某个元素小,则交换位置
        arr[j + gap] = arr[j]
      }
      arr[j + gap] = key
    }
    gap = Math.floor(gap / 2)
  }
  return arr
}

归并排序

在这里插入图片描述

核心算法:

1.先使用递归将数组划分成一个个长度为1的数组

2.将两个有序的数组合并成一个有序的数组,方法是:依次比较左右两个数组中第一个元素的大小,小的元素放到新数组的末尾,并删除该元素

function mergeSort(arr) {
  // 将两个有序的数组合并成一个有序的数组
  function merge(leftArr, rightArr) {
    console.log(leftArr, rightArr);
    let newArr = []
    while (leftArr.length && rightArr.length) {
      // 依次比较左右两个数组中第一个元素的大小,小的元素放到新数组中
      if (leftArr[0] > rightArr[0]) {
        newArr.push(rightArr.shift())
      } else {
        newArr.push(leftArr.shift())
      }
    }
    return [...newArr, ...leftArr, ...rightArr]
  }

  // 数组中只有一个元素,是有序的
  if (arr.length === 1) return arr
  let mid = Math.floor(arr.length / 2)
  // 将数组一分为二
  let leftArr = mergeSort(arr.slice(0, mid)) 
  let rightArr = mergeSort(arr.slice(mid))
  return merge(leftArr, rightArr)
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/650411.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java替换Jar文件中的class文件方法

备份源文件 文件不重要的话可以不需要备份&#xff0c;线上环境务必备份方便回滚 mkdir bak cp test.jar bak 查看class文件所在目录 jar -tvf test.jar | grep Time.class 标红内容就是需要替换的class文件&#xff0c;如果有多个文件需要替换依次执行2&#xff0c;3步骤…

webSocket实时通信02——基于Spring【纯后端——JAVA】

这里是基于Spring整合websoket后来实现的实时通信&#xff0c;这里只有java的代码&#xff0c;通过在线网站 http://www.websocket-test.com/测试即可 1. 导包 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-star…

网络安全合规-职业发展路线

网络安全人才一将难求&#xff0c;缺口高达 95% 在以前&#xff0c;很多政企单位在进行 IT 部门及岗位划分时&#xff0c;只有研发和运维部门&#xff0c;安全人员直接归属到基础运维部&#xff1b;而现在&#xff0c;越来越多单位为了满足国家安全法律法规的要求&#xff0c;…

终极攻略!如何彻底防止Selenium被检测!

在使用Selenium进行爬虫时&#xff0c;许多朋友都会遇到各种反爬措施。 实际上&#xff0c;在绝大多数情况下&#xff0c;网站轻而易举地能够检测出你正在使用WebDriver而非标准浏览器。 本文将详细介绍如何有效防止检测的方法。 在一篇公众号文章《别去送死了。Selenium 与…

【重磅】智能未来 —— 人工智能与城乡规划的交叉对话(CSDN深圳城市开发者社区首场线下技术交流活动)

文章目录 活动主题活动海报活动时间活动地点互动有礼加入有礼赠书简介特别说明 活动主题 智能未来-人工智能与城乡规划的交叉对话 —— 以 AI 为核心主题&#xff0c;探索 AI 在 智慧城市、智能视频、智能编程 等重点领域的技术发展和实战落地。 活动海报 活动时间 2023.06…

加密与解密 调试篇 动态调试技术 (五)-WinDbg

windbg主要厉害的地方是在他可以对内核调试 并且本身微软的产品 对windows调试适配度够高 注意 windbg给出的图形操作并不好用 主要是使用命令行来进行操作 我们省略安装 直接进入调试 file 可以打开软件 可以附加也可以分析dump文件还可以进行内核和 远程调试内核调试分为…

招商基金资深架构师教你如何搭建统一监控平台

随着数字化进程的加速和业务的高速发展&#xff0c;系统的复杂程度日益升级&#xff0c;为确保业务系统的连续性和稳定性&#xff0c;越来越多的企业想要建设统一的监控平台&#xff0c;但却不知道从哪里开始着手。比如&#xff1a; 有些企业会直接将监控系统页面集成到统一监…

SpringBoot配置文件application.yml的理解

一、存放位置分类 1.当前项目根目录下的config目录下 2.当前项目的根目录下 3.resources目录下的config目录下 4.resources目录下 按照这上面的顺序&#xff0c;4个配置文件的优先级依次降低。 二、自定义存放位置和自定义命名 自定义存放位置和自定义配置文件命令和appl…

Python从Excel读取数据并使用Matplotlib绘制成二维图像

本课程实现使用 Python 从 Excel 读取数据&#xff0c;并使用 Matplotlib 绘制成二维图像。这一过程中&#xff0c;将通过一系列操作来美化图像&#xff0c;最终得到一个可以出版级别的图像。本课程对于需要书写实验报告&#xff0c;学位论文&#xff0c;发表文章&#xff0c;做…

Vue中的虚拟Dom,diff算法,以及diff的优化

virtual dom&#xff1a; 关键词&#xff1a; 1、 template 2、渲染函数 3、 vnode(virtual dom) 4、patch(diff算法) 5、view Vue.js通过编译将template 模板转换成渲染函数(render ) &#xff0c;执行渲染函数就可以得到一个虚拟节点树 VNode 虚拟节点&#xff1a;它可以代…

C++ 中的新成员

C 中的动态内存分配 C 中通过 new 关键字进行动态内存申请 C 中的动态内存申请是基于类型进行的 delete 关键字用于内存释放 new 关键字和 malloc 函数的区别 new 关键字是 C 的一部分 malloc 是由 C 库提供的函数 new 以具体类型为单位进行内存分配 malloc 以字节为单位…

Jenkins ——pipeline入门教程

一、什么是pipeline 什么是Pipeline&#xff1f;简单来说&#xff0c;就是一套运行于Jenkins上的工作流框架&#xff0c;将原本独立运行于单个或者多个节点的任务连接起来&#xff0c;实现单个任务难以完成的复杂发布流程&#xff08;实用场景&#xff1a;将多个Jenkins构建任…

最优化方法Python计算:一元函数搜索算法——二次插值法

已知连续函数 f ( x ) f(x) f(x)在 x ∗ x^* x∗近旁存在最优解 x 0 x_0 x0​。对博文《最优化方法Python计算&#xff1a;连续函数的单峰区间计算》讨论的 f ( x ) f(x) f(x)单峰区间的包围算法稍加修改&#xff0c;可算得 f ( x ) f(x) f(x)包含 x 0 x_0 x0​的单峰区间 [ a …

pandas---删除重复行、映射、异常值检测与过滤、抽样

1. 删除重复行 使用duplicated()函数检测重复的行。 返回布尔类型的Series对象&#xff0c;每个元素对应一行&#xff0c;如果该行不是第一次出现&#xff0c;则元素为True。 def make_df(indexs, columns): data [[str(j)str(i) for j in columns] for i in indexs]df …

中国人民大学与加拿大女王大学金融硕士——用更长远的眼光,展望未来

职场中遇到瓶颈&#xff0c;大家都迫切希望改变自己所处的环境&#xff0c;但却不愿意改变自己&#xff0c;所以他们自己仍然是被束缚的。如果一个人不能够从自我拷问的状态中解脱出来&#xff0c;他就永远也不可能实现自己心中的目标。我们要用更长远的眼光去展望未来&#xf…

NAVIGATE 领航者峰会:记忆科技携手新华三,以存储创新释放数据价值

近日&#xff0c;由紫光集团和新华三集团主办的2023 NAVIGATE 领航者峰会在杭州举行。本届峰会的主题为“精耕务实&#xff0c;为时代赋智慧”&#xff0c;围绕该主题&#xff0c;国内外数千名技术领导者汇聚一堂&#xff0c;探讨数字经济的创新未来。作为IT硬件领域的重要厂商…

vue + g6 实现树级结构(compactBox 紧凑树)

G6文档 自定义节点 G6.registerNode("dom-node",{draw: (cfg, group) > {let str <div classitem-box catalog-node ${cfg.isSelected ? "is-selected" : ""} ${cfg.status}-box οnclickhandleDetail("${cfg.id}") id&quo…

JMeter压测如何分配业务比例?

在进行综合场景压测时&#xff0c;由于不同的请求&#xff0c;要求所占比例不同&#xff0c;那如何实现呢&#xff1f; 有人说将这些请求分别放到单独的线程组下&#xff0c;然后将线程组的线程数按照比例进行配置&#xff0c;这种方法不是很好&#xff0c;想想&#xff0c;不…

5G是如何提升通行能力的?5G毫米波到底有多快?

高速公路&#xff0c;可以通过多层交通、多条车道、车道方向、车辆容量、货物包装、驾驶司机等多个因素&#xff0c;提升通行能力。 我们把5G比作高速公路&#xff0c;那么&#xff0c;5G是如何提升自身通行能力的呢&#xff1f;5G毫米波&#xff0c;到底能有多快呢&#xff1f…

跨越时空的教育:在线培训系统的全球化

随着全球化的发展&#xff0c;跨越时空的教育已经成为现实。在线培训系统可以打破地域限制&#xff0c;让学生能够接受来自世界各地的教育资源。这种新型教育模式具有巨大的潜力和优势。 在线培训系统是指通过互联网提供的远程教育服务。它可以通过网络平台、视频教育、虚拟课…