【C/C++数据结构 - 2】:稳定性与优化揭秘,揭开插入排序、希尔排序和快速排序的神秘面纱!

文章目录

  • 排序的稳定性
  • 插入排序
    • 插入排序的优化
  • 希尔排序
  • 快速排序

排序的稳定性

稳定排序:排序前2个相等的数在序列中的前后位置顺序和排序后它们2个的前后位置顺序相同。(比如:冒泡、插入、基数、归并)

非稳定排序:排序前2个数的相对位置在排序后会发生改变。(比如:选择、快速、希尔、堆等)

插入排序

插入排序,一般也被称为直接插入排序。对于少量元素的排序,它是一个有效的算法。

插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。

在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动。

void Insertion_Sort(int a[], int len)
{//外层循环 - 插入数据量for (int i = 1; i < len; i++){//内层循环 - 每一趟需要做的事情for (int j = i - 1; j > -1; j--){if (a[j]>a[j + 1]){int temp = a[j];a[j] = a[j + 1];a[j + 1] = temp;}}}
}

插入排序的优化

在下面函数中,通过使用一个临时变量temp来保存当前需要插入的元素。外层循环通过对整个待排序序列进行遍历,从第二个元素开始(下标为1),将当前元素保存在temp中。

然后,内层循环从当前元素的前一个元素开始向前遍历,直到找到合适的位置插入temp。在内层循环中,如果当前遍历到的元素大于temp,就将该元素后移一位,给temp腾出位置。

内层循环结束后,将temp插入到合适的位置,即将其赋值给a[j+1],这样就完成了一次元素的插入。

通过这种方式,不断地将元素逐个地插入到已排序的序列中,最终得到一个完全有序的序列。

void Insertion_Sort(int a[], int len)
{int temp, i, j;//外层循环 - 插入数据量for (i = 1; i < len; i++){temp = a[i];//内层循环 - 每一趟需要做的事情for (j = i - 1; j > -1 && a[j] > temp; j--){a[j + 1] = a[j];}//移动结束a[j + 1] = temp;}
}

希尔排序

希尔排序(Shell Sort)是一种改进的插入排序算法,也被称为“缩小增量排序”(Diminishing Increment Sort)。希尔排序通过将待排序序列分割成多个子序列来进行排序,最终将这些子序列逐步合并为一个有序序列。

希尔排序的核心思想是通过定义一个增量序列(也称为间隔序列),将待排序序列划分成若干个子序列,并对这些子序列分别进行插入排序。随着排序的进行,增量序列会不断减小,直到变为1,此时对整个序列进行一次插入排序,最终完成排序。

希尔排序的步骤如下:

  • 首先确定一个增量序列,一般选择初始增量为序列长度的一半,然后每次将增量折半,直到增量变为1。

  • 对每个增量进行插入排序,即将待排序序列划分成若干个子序列,对每个子序列进行插入排序。

  • 在每次插入排序中,按照增量的大小,将元素分组,对每组进行插入排序。

  • 不断缩小增量,重复步骤2和步骤3,直到增量为1,进行最后一次插入排序,完成排序。

举个例子:

  • 如下图所示,现有一序列:8、5、7、3、6、1、2、8,选择初始增量为序列长度的一般,即初始增量为4(分为四个组,标红数字所示)。
    在这里插入图片描述
  • 第一次交换(组别增量为4)
    • 8和6为一组,5和1为一组……,队每组中的数比较排序,(例:第一组排序,8比6大,则8、6互换位置,以此类推)排序后的结果如下图所示。
      在这里插入图片描述
  • 第二次交换(组别增量由4变为2)如下图所示。
    在这里插入图片描述
    • 先对1组进行比较,首先6作为已序。
    • 第一次比较:1组的第一个数(6)与第二个数(2)进行比较,2<6小,插入到6的位置,6换到2的位置。
    • 第二次比较:1组的第二个数(6)与第三个数(8)进行比较,6<8,则不进行插入。
    • 第三次比较:1组的第三个数(8)与第4个数(7)进行比较,8>7,所以7插入到8的位置,8换到7的位置。
    • 最终1组排序的结果如下:
      在这里插入图片描述
    • 同理,对2组进行比较后的结果如下图所示。
      在这里插入图片描述
  • 第三次交换(组别增量从2变为1)
    在这里插入图片描述
    • 组别增量变为1之后,对整体做插入排序,结果如下。
      在这里插入图片描述

希尔排序函数:

//希尔排序
void Shell_Sort(int a[], int len)
{int temp, i, j, n = 0;//增量分组int jump = len >> 1;while (jump != 0){//外层循环 - 插入数据量for (i = jump; i < len; i++){temp = a[i];//内层循环for (j = i - jump; j >= 0 && a[j]>temp; j -= jump){a[j + jump] = a[j];n += 1;}//移动结束a[j + jump] = temp;}//增量更新jump >>= 1;}
}

分别在优化后的插入排序函数和希尔排序中定义一个变量n,用来统计各自进行数据交换的次数,结果如下:

在这里插入图片描述

插入排序交换的次数约是希尔排序交换次数的两倍!

快速排序

快速排序(Quicksort)是对冒泡排序的一种改进。

快速排序的核心思想是通过分治法将一个大的待排序序列逐步地分割成小的子序列,然后对这些子序列进行排序,最终得到一个有序序列。具体步骤如下:

  1. 选择一个基准元素(pivot),可以是序列中的任意一个元素。
  2. 将序列分为两部分,小于等于基准元素的部分和大于基准元素的部分。可以通过两个指针 i 和 j 来实现,开始时 i 指向序列的第一个元素,j 指向序列的最后一个元素。
    • 从左向右找出第一个大于基准元素的元素,记为 a。
    • 从右向左找出第一个小于等于基准元素的元素,记为 b。
    • 如果 i < j,则交换 a 和 b 的位置,然后继续找下一对 a 和 b。
    • 如果 i >= j,则停止查找。
  3. 将基准元素与 j 所指向的元素交换位置,即将基准元素放在合适的位置。
  4. 递归地对基准元素左边和右边的子序列进行快速排序。

以下是一个使用 C 语言实现的快速排序代码示例:

#include <stdio.h>// 交换两个元素的值
void swap(int *a, int *b) {int temp = *a;*a = *b;*b = temp;
}// 快速排序的递归函数
void quickSort(int arr[], int low, int high)
{if (low < high) {int pivot = arr[low];  // 选择第一个元素作为基准元素int i = low, j = high;while (i < j){while (i < j && arr[j] > pivot) {j--;}while (i < j && arr[i] <= pivot) {i++;}if (i < j) {swap(&arr[i], &arr[j]);}}swap(&arr[low], &arr[i]);quickSort(arr, low, i - 1);  // 对左边子序列进行快速排序quickSort(arr, i + 1, high); // 对右边子序列进行快速排序}
}// 打印数组元素
void printArray(int arr[], int size) 
{for (int i = 0; i < size; i++) {printf("%d ", arr[i]);}printf("\n");
}int main() 
{int arr[] = {8, 5, 7, 3, 6, 1, 2, 8};int size = sizeof(arr) / sizeof(arr[0]);printf("原始数组:");printArray(arr, size);quickSort(arr, 0, size - 1);printf("排序后数组:");printArray(arr, size);return 0;
}

输出结果:

在这里插入图片描述

分析程序:
代码首先定义了一个 swap 函数用于交换两个元素的值。然后,quickSort 函数使用递归实现了快速排序的具体操作。最后,在 main 函数中创建一个待排序的数组,并调用 quickSort 函数对数组进行排序。最终,通过调用 printArray 函数打印排序后的数组。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

商品API接口优秀案例 │ 国家电网办公物资电商化采购项目API解决方案

苏宁易购集团股份有限公司&#xff08;以下简称“苏宁”&#xff09;作为中国领先的O2O智慧零售商&#xff0c;在互联网、物联网、大数据盛行的时代&#xff0c;持续推进智慧零售和线上线下融合战略&#xff0c;全品类经营&#xff0c;全渠道运营&#xff0c;开放苏宁物流云、数…

video_topic

使用qt5,ffmpeg6.0,opencv&#xff0c;os2来实现。qt并非必要&#xff0c;只是用惯了。 步骤是&#xff1a; 1.读取rtsp码流&#xff0c;转换成mat图像 2.发送ros::mat图像 项目结构如下&#xff1a; videoplayer.h #ifndef VIDEOPLAYER_H #define VIDEOPLAYER_H#include …

机器学习笔记 - 车道检测的几种深度学习方法

一、简述 人们在打造自动驾驶汽车时首先想到的就是实现车道检测。这是 Tesla 和 mobileye 所说的“强制性”任务,也是 Sebastian Thrun(自动驾驶汽车教父)在接受采访时所说的首要任务。 这个方向有很多传统的 OpenCV 算法,这些算法由不再使用的非常旧的函数组成。目前全部都…

LabVIEW玩转魔方

LabVIEW玩转魔方 使用LabVIEW创建一个3D魔方&#xff0c;并找出解谜题的秘密&#xff0c;给朋友留下深刻深刻的印象。游戏中内置的机制使每张脸都能独立转动&#xff0c;从而混合颜色。要解决难题&#xff0c;每个面必须是相同的纯色 魔方的奥秘在于它的简单性和不可解性。这是…

基于springboot实现音乐网站与分享平台项目【项目源码+论文说明】

摘要 本论文主要论述了如何使用JAVA语言开发一个音乐网站与分享平台 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述音乐网站与分享平台的当前背景以及系统开…

Python 人工智能 Machine Learning 机器学习基础知识点详细教程(更新中)

Artificial Intelligence 人工智能基本介绍 人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。它试图了解智能的实质&#xff0c;并生产出一种新的能以人类智…

VMware使用ubuntu安装增强功能实现自动缩放

VMware使用ubuntu安装增强功能实现自动缩放 1.下载 VMware Tools2.安装tool 1.下载 VMware Tools 1.需要先弹出DVD 2.虚拟机-安装VMware Tools 进入终端 3.把media下的VMware压缩包拷贝到home/下 4.去home下解压 2.安装tool 进入vmware-tools-distrib sudo ./vmware-ins…

微信小程序备案内容常见问题汇总

一、备案时间点 自2023年09月01日起,新的微信小程序,必须备案后才能上架; 在2024年03月31日前,所有小程序都必须完成备案; 于2024年04月01日起,对未备案小程序进行清退处理。 微信小程序备案系统已于9月4日上线。 二、备案流程 [找备案入口]–[填主体信息]–[填小程…

QE01/QA11/QA02屏幕增强

1、业务需求 需要对来料检验增加“合格数量”和“不合格数量”字段&#xff0c;涉及三个增强开发 2、QE01\QE02\QE03\QE51N屏幕增强 增强表 增强点BADI&#xff1a;QEEM_SUBSCREEN_5000 创建程序&#xff0c;包含子屏幕&#xff0c;在增强点中调用 在程序屏幕中绘制字段 在输…

asp.net售后维修管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net 售后维修管理系统 是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为sqlserver2008&#xff0c;使用c#语 言开发 asp.net售后维修管理系统1 二、…

python openai playground使用教程

文章目录 playground介绍Playground特点模型设置和参数选择四种语言模型介绍 playground应用构建自己的playground应用playground python使用 playground介绍 OpenAI Playground是一个基于Web的工具&#xff0c;旨在帮助开发人员测试和尝试OpenAI的语言模型&#xff0c;如GPT-…

【大数据】Apache Hive数仓(学习笔记)

一、数据仓库基础概念 1、数仓概述 数据仓库&#xff08;数仓、DW&#xff09;&#xff1a;一个用于存储、分析、报告的数据系统。 OLAP&#xff08;联机分析处理&#xff09;系统&#xff1a;面向分析、支持分析的系统。 数据仓库的目的&#xff1a;构建面向分析的集成化数据…

9、Docker 安装 Redis

1、下载镜像 docker pull redis:3.2.10 2、本机创建redis目录并修改配置文件 1&#xff09;创建目录 mkdir /usr/local/redis 2&#xff09;进入redis目录 cd /usr/local/redis 3&#xff09;创建data目录 mkdir data 4&#xff09;创建redis.conf文件 vi redis.conf 5&a…

网站的搭建与应用|企业APP软件定制开发|小程序

网站的搭建与应用|企业APP软件定制开发|小程序 网站是一种数字化媒体&#xff0c;它可以将我们的信息传递给全球的用户&#xff0c;让更多的人了解我们、了解我们的产品和服务。那么&#xff0c;如何搭建一个网站呢&#xff1f;下面&#xff0c;我将为大家介绍一下网站的建设步…

NIO基础-ByteBuffer,Channel

文章目录 1. 三大组件1.1 Channel1.2 Buffer1.2 Selector 2.ByteBuffer2.1 ByteBuffer 正确使用姿势2.2 ByteBuffer 结构2.3 ByteBuffer 常见方法分配空间向 buffer 写入数据从 buffer 读取数据mark 和 reset字符串与 ByteBuffer 互转分散度集中写byteBuffer黏包半包 3. 文件编…

Vulnhub系列靶机-Raven2

文章目录 Raven2 渗透测试1. 信息收集1.1 主机探测1.2 端口扫描1.3 目录爆破 2. 漏洞探测3. 漏洞利用3.1 msfconsole3.2 交互式shell 4. 权限提升 Raven2 渗透测试 1. 信息收集 1.1 主机探测 arp-scan -l1.2 端口扫描 nmap -p- -A 192.168.188.213通过nmap工具进行端口扫描…

当想为SLB申请公网域名时,缩写是什么意思

SLB的缩写是Server Load Balancer&#xff0c;即服务器负载均衡器。 是一种内网吗? 不&#xff0c;SLB&#xff08;Server Load Balancer&#xff09;是一种位于应用程序和网络之间的设备或服务&#xff0c;用于在多个服务器之间分发流量、负载均衡以及提供高可用性。它通常…

2核4G游戏服务器推荐(阿里云/腾讯云/华为云)

2核4G游戏服务器推荐&#xff0c;首选腾讯云2核4G5M带宽轻量应用服务器218元一年、阿里云2核4G4M带宽轻量应用服务器297元一年&#xff0c;华为云2核2G3M云耀L服务器95元一年&#xff0c;阿腾云来详细说下2核4G游戏服务器推荐配置大全&#xff1a; 目录 2核4G游戏服务器推荐 …

Qt应用开发(基础篇)——树结构视图 QTreeView

一、前言 QTreeView类继承于QAbstractItemView类&#xff0c;提供了一个树结构视图的模型。 视图基类 QAbstractItemView QTreeView默认为Model/View实现&#xff0c;下面是一个使用QFileSystemModel和QTreeView的结合&#xff0c;显示系统文件结构的实例。 QFileSystemModel …

pycharm中快速对比两个.py文件

在学习一个算法的时候&#xff0c;就想着自己再敲一遍代码&#xff0c;结果最后出现了一个莫名其妙的错误&#xff0c;想跟源文件对比一下到底是在哪除了错&#xff0c;之前我都是大致定位一个一个对比&#xff0c;想起来matlab可以快速查找出两个脚本文件(.m文件)的区别&#…