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日

相关文章

  • 浅谈C++内存分配及变长数组的动态分配

    浅谈C++内存分配及变长数组的动态分配 介绍 在C++中,内存分配是一个重要的概念,它决定了程序在运行时如何使用和管理内存。本文将详细讲解C++中的内存分配方式,并重点介绍变长数组的动态分配。 静态内存分配 静态内存分配是指在编译时为变量分配固定大小的内存空间。这种分配方式适用于在编译时已知变量大小的情况。例如: int staticArray[10]; /…

    other 2023年8月1日
    00
  • 如何快速整理清除电脑鼠标右键菜单

    当我们长时间使用电脑时,鼠标右键菜单可能会变得非常繁杂,这可能会影响我们的工作效率。本文将详细介绍如何快速整理清除电脑鼠标右键菜单。 第一步:备份右键菜单注册表 在进行任何修改操作之前,务必先备份您的注册表,以免意外删除重要的菜单或设置。您可以按照以下步骤备份注册表: 打开“运行”对话框,可以通过按下键盘上的Win+R组合键打开。 输入regedit命令并按…

    other 2023年6月27日
    00
  • Nginx用户认证配置方法详解(域名/目录)

    下面是Nginx用户认证配置方法详解的完整攻略。 什么是Nginx用户认证? 在Nginx中,用户认证是指通过验证用户名和密码,来限制特定路径或资源只能被特定用户访问。Nginx用户认证可以用于保护网站后台管理页面、个人文件存储和对特定内容的访问等场景。 Nginx用户认证配置方法 步骤1:安装htpasswd工具 htpasswd是一个用于生成和更新基于文…

    other 2023年6月27日
    00
  • openbabel的安装与使用

    什么是OpenBabel? OpenBabel是一种化学信息学工具,用于处理化学结构数据。它可以读取、写入和转换多种化学文件格式,如SMILES、MOLPDB等。OpenBabel还提供了一些学计算功能,如分子对齐、药物性质预测等。 OpenBabel的安装 OpenBabel可以在Windows、Linux和Mac OS X等操作系统上安装。以下是在Ubu…

    other 2023年5月7日
    00
  • Android常见控件使用详解

    Android常见控件使用详解 本篇攻略主要介绍 Android 常见控件的使用,包括文本框、按钮、列表、图片等控件的创建和使用方法。在 Android 开发中,掌握常见控件的使用是非常必要的,不仅能够丰富应用的功能和样式,也能够提高用户的使用体验。 文本框 文本框是 Android 开发中最基础的控件之一,主要用于显示文本信息。常见的文本框有 TextVi…

    other 2023年6月27日
    00
  • Android自定义悬浮按钮效果

    Android自定义悬浮按钮效果 在手机应用开发中,悬浮按钮已经成为了流行的用户界面元素。悬浮按钮可以通过相应的手势实现一些应用操作,比如向上滑动打开应用菜单、向下滑动隐藏悬浮按钮等等。本文将介绍如何使用Android SDK来自定义悬浮按钮效果。 步骤1:创建悬浮按钮控件 为了实现悬浮按钮的效果,需要创建自定义的View控件。下面是一个简单的悬浮按钮控件代…

    other 2023年6月25日
    00
  • Java NIO 中 Selector 解析

    Java NIO 中 Selector 解析 什么是Selector Selector是Java NIO框架中一个重要的组件,它可以监控多个通道(channel)的IO状况,当一个或多个通道可以进行IO操作时,Selector会自动地将通道加入到已选择的键集合SelectionKey中,并通过SelectionKey来标识这些通道,从而使得单线程能够处理多个…

    other 2023年6月27日
    00
  • css样式底部平均分布

    CSS样式底部平均分布 在网站开发过程中,我们经常需要将一排元素展示在页面底部,比如页脚链接、社交媒体图标等等。而如果我们希望这些元素在底部平均分布,应该怎么做呢? 下面,我们来介绍一种简单易用的CSS样式,可以轻松地实现底部元素平均分布的效果。 使用Flex布局 CSS3引入的弹性盒子布局(Flexbox)为我们提供了更加便捷的布局方式。下面的代码片段展示…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部