Java数据结构和算法之冒泡,选择和插入排序算法

Java数据结构和算法之冒泡、选择和插入排序算法

冒泡排序算法

算法思路

冒泡排序是一种基础的排序算法,它通过比较相邻元素的大小并交换位置,将最大(或最小)的元素逐步“冒泡”到序列的最后,从而完成排序。

具体地,冒泡排序的过程如下:

  1. 从序列的第一个元素开始,依次比较相邻的两个元素,如果前面的元素大于后面的元素,则交换它们的位置。
  2. 继续依次比较相邻的元素,直到序列的倒数第二个元素为止。
  3. 重复执行步骤 1、2,直到序列全部排序完成。

示例说明

下面是一组示例数据:

int[] arr = {4, 2, 8, 3, 1};

使用冒泡排序算法对其进行排序,可得到如下过程:

// 第 1 轮
arr[0] 和 arr[1] 比较,arr[0] < arr[1],不交换位置
arr[1] 和 arr[2] 比较,arr[1] > arr[2],交换位置,arr 变成 {4, 8, 2, 3, 1}
arr[2] 和 arr[3] 比较,arr[2] < arr[3],不交换位置
arr[3] 和 arr[4] 比较,arr[3] > arr[4],交换位置,arr 变成 {4, 8, 2, 1, 3}

// 第 2 轮
arr[0] 和 arr[1] 比较,arr[0] < arr[1],不交换位置
arr[1] 和 arr[2] 比较,arr[1] < arr[2],不交换位置
arr[2] 和 arr[3] 比较,arr[2] > arr[3],交换位置,arr 变成 {4, 2, 1, 8, 3}
arr[3] 和 arr[4] 比较,arr[3] < arr[4],不交换位置

// 第 3 轮
arr[0] 和 arr[1] 比较,arr[0] > arr[1],交换位置,arr 变成 {2, 4, 1, 8, 3}
arr[1] 和 arr[2] 比较,arr[1] < arr[2],不交换位置
arr[2] 和 arr[3] 比较,arr[2] > arr[3],交换位置,arr 变成 {2, 1, 4, 8, 3}
arr[3] 和 arr[4] 比较,arr[3] > arr[4],交换位置,arr 变成 {2, 1, 4, 3, 8}

// 第 4 轮
arr[0] 和 arr[1] 比较,arr[0] > arr[1],交换位置,arr 变成 {1, 2, 4, 3, 8}
arr[1] 和 arr[2] 比较,arr[1] < arr[2],不交换位置
arr[2] 和 arr[3] 比较,arr[2] > arr[3],交换位置,arr 变成 {1, 2, 3, 4, 8}

// 第 5 轮
arr[0] 和 arr[1] 比较,arr[0] < arr[1],不交换位置
arr[1] 和 arr[2] 比较,arr[1] < arr[2],不交换位置
arr[2] 和 arr[3] 比较,arr[2] < arr[3],不交换位置
arr[3] 和 arr[4] 比较,arr[3] < arr[4],不交换位置

可见,经过 5 轮排序,序列被正确排序。在最坏情况下,即原序列为逆序排列时,冒泡排序算法的时间复杂度为 O(n^2)。

选择排序算法

算法思路

选择排序算法也是一种基础的排序算法,它通过和冒泡排序不同的思路进行排序。选择排序过程中,依次遍历整个序列,每次找到未排序部分中的最小值(或最大值),并将其放置在已排序部分的末尾。

具体地,选择排序的过程如下:

  1. 设置一个变量 minIndex,初始值和第一个未排序元素的下标相同。
  2. 依次遍历未排序部分的每个元素,将其与 minIndex 指向的元素进行比较,如果找到一个更小(或更大)的元素,则将 minIndex 更新为该元素的下标。
  3. 遍历到序列末尾后,将找到的最小值(或最大值)直接与未排序部分的第一个元素进行交换,从而将其放置在已排序部分的末尾。
  4. 重复执行步骤 2、3,直到整个序列全部排序完成。

示例说明

下面是一组示例数据:

int[] arr = {4, 2, 8, 3, 1};

使用选择排序算法对其进行排序,可得到如下过程:

// 第 1 轮
从 arr[0] 开始遍历,找到 arr[4] 最小,将 arr[0] 和 arr[4] 交换,arr 变成 {1, 2, 8, 3, 4}

// 第 2 轮
从 arr[1] 开始遍历,找到 arr[3] 最小,将 arr[1] 和 arr[3] 交换,arr 变成 {1, 2, 8, 3, 4}

// 第 3 轮
从 arr[2] 开始遍历,找到 arr[3] 最小,将 arr[2] 和 arr[3] 交换,arr 变成 {1, 2, 3, 8, 4}

// 第 4 轮
从 arr[3] 开始遍历,找到 arr[4] 最小,将 arr[3] 和 arr[4] 交换,arr 变成 {1, 2, 3, 4, 8}

// 第 5 轮
遍历完成,整个序列已全部排序完成。

可见,经过 5 轮排序,序列被正确排序。与冒泡排序算法相同,选择排序算法的时间复杂度也为 O(n^2)。

插入排序算法

算法思路

插入排序算法是一种较为高效的排序算法,尤其适用于对有序或基本有序的数据进行排序。插入排序算法的基本思路是将未排序部分中的元素逐个插入到已排序部分中相应的位置。

具体地,插入排序的过程如下:

  1. 将序列分为已排序部分和未排序部分,初始时已排序部分只包含第一个元素,未排序部分包含剩余所有元素。
  2. 遍历未排序部分的每个元素,将其依次插入到已排序部分中相应的位置。具体地,从序列的第二个元素开始,将其与已排序部分的元素依次比较,直到找到第一个比其大(或小)的元素,然后将该元素插入其前面,从而保证已排序部分仍然有序。
  3. 重复执行步骤 2,直到未排序部分全部加入已排序部分为止。

示例说明

下面是一组示例数据:

int[] arr = {4, 2, 8, 3, 1};

使用插入排序算法对其进行排序,可得到如下过程:

// 第 1 轮
已排序部分只包含 arr[0],未排序部分包含 arr[1] 到 arr[4]。取出 arr[1],将其与 arr[0] 比较,发现 arr[1] 较小,将其插入 arr[0] 前面,此时已排序部分为 {2, 4},未排序部分为 {8, 3, 1}。
取出 arr[2],将其依次与已排序部分的元素比较,发现它应该插入到 arr[1] 后面,此时已排序部分为 {2, 4, 8},未排序部分为 {3, 1}。
取出 arr[3],将其依次与已排序部分的元素比较,发现它应该插入到 arr[1] 前面,此时已排序部分为 {2, 3, 4, 8},未排序部分为 {1}。
取出 arr[4],将其依次与已排序部分的元素比较,发现它应该插入到 arr[0] 前面,此时已排序部分为 {1, 2, 3, 4, 8},未排序部分为空。

// 第 2 轮
整个序列已全部排序完成。

可见,经过 2 轮排序,序列被正确排序。相比冒泡排序和选择排序,插入排序的时间复杂度较低,最好情况下为 O(n),平均情况下为 O(n^2)。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java数据结构和算法之冒泡,选择和插入排序算法 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 基于HTTP协议实现简单RPC框架的方法详解

    基于HTTP协议实现简单RPC框架的方法详解 什么是RPC框架? RPC(Remote Procedure Call)远程过程调用,是一种计算机通信协议。它允许像调用本地服务一样调用远程服务。 RPC框架就是一种基于RPC协议的远程调用解决方案,它可以让你跨越不同的机器和操作系统实现不同进程的数据交换和通信。RPC框架在服务端和客户端间建立了一个抽象层,隐藏…

    other 2023年6月27日
    00
  • 关于python:如何使用pandas删除第一行?

    以下是关于“关于python:如何使用pandas删除第一行?”的完整攻略,包含两个示例。 关于Python: 如何使用pandas删除第一行? 在使用pandas处理数据时,有时需要删除第一行。以下是关于如何使用pandas删除第一行的详细攻略。 1. 使用pandas的drop方法 pandas的DataFrame对象提供了drop方法,可以删除指定的行…

    other 2023年5月9日
    00
  • 如何正确的进行网站入侵渗透测试

    如何正确的进行网站入侵渗透测试 环境准备 安装Kali Linux或其他Linux发行版 安装常用的渗透工具,如Burp Suite、Nmap、Metasploit、SQLMap等 准备一个合法的目标网站,并获得合法的授权进行测试 渗透测试准备 收集目标网站的相关信息,包括IP地址、端口、响应信息、网站架构等 分析目标网站的安全漏洞,如SQL注入、XSS注入…

    other 2023年6月27日
    00
  • mysql获取分组后每组的最大值实例详解

    以下是使用MySQL获取分组后每组的最大值的完整攻略: 步骤1:创建示例数据表 首先,创建一个示例的数据表,用于演示获取分组后每组的最大值。假设我们有一个名为orders的表,包含以下字段:order_id、group_id和amount。 CREATE TABLE orders ( order_id INT PRIMARY KEY, group_id IN…

    other 2023年10月17日
    00
  • C++ 类中有虚函数(虚函数表)时 内存分布详解

    下面是关于“C++ 类中有虚函数(虚函数表)时 内存分布详解”的完整攻略: 1. 什么是虚函数 在 C++ 中,虚函数是指在基类中使用 virtual 关键字声明的成员函数。虚函数的特点是,在继承关系中,它能够被子类重写并被动态绑定。 2. 虚函数表 为了实现虚函数的动态绑定,编译器会在包含虚函数的类中生成一个虚函数表(Virtual Table,VTABL…

    other 2023年6月27日
    00
  • 如何修复快捷方式lnk文件的打开方式

    如何修复快捷方式(.lnk)文件的打开方式 快捷方式(.lnk)文件是指向其他文件或文件夹的快速访问链接。如果你的快捷方式文件的打开方式出现问题,可能会导致无法正常打开目标文件或文件夹。下面是修复快捷方式文件打开方式的完整攻略: 步骤一:重置文件关联 打开“控制面板”。 在控制面板中,选择“默认程序”。 点击“关联一个文件类型或协议与特定的程序”。 在文件类…

    other 2023年8月6日
    00
  • echarts移动端中例子总结。

    以下是详细讲解“ECharts移动端中例子总结”的完整攻略,包括ECharts移动端的基本使用、ECharts动端的图表类型和ECharts移动端的地图类型,同时提供两个示例说明。 ECharts移动端中例子总结 ECharts是一个基于JavaScript的开源可视化库,可以用于创建各种类型图表和地图。本文将介绍ECharts移动端中的例子总结,包括ECh…

    other 2023年5月9日
    00
  • 3DMAX文件损坏无法打开怎么恢复备份文件?

    3DMAX文件损坏无法打开的恢复备份文件攻略 如果你的3DMAX文件损坏无法打开,以下是一些恢复备份文件的攻略,希望能帮到你。 步骤1:检查备份文件 首先,你需要检查是否有3DMAX文件的备份文件。备份文件通常具有类似于原始文件的名称,但可能带有日期、时间戳或其他标识符。这些备份文件通常保存在与原始文件相同的文件夹中,但可能具有不同的文件扩展名,如\”.ba…

    other 2023年8月5日
    00
合作推广
合作推广
分享本页
返回顶部