惊叹数据结构之美,品味排序算法之妙:对四大排序的详细介绍

惊叹数据结构之美,品味排序算法之妙:对四大排序的详细介绍
大家好,这里是小编的博客频道
小编的博客:就爱学编程
很高兴在ZEEKLOG这个大家庭与大家相识,希望能在这里与大家共同进步,共同收获更好的自己!!!

本文目录


在这里插入图片描述

那接下来就让我们开始遨游在知识的海洋!

正文


一、冒泡排序(Bubble Sort)

原理:通过重复遍历要排序的序列,每次比较相邻的两个元素并交换它们的位置,如果它们的顺序错误(即前一个元素大于后一个元素)。这样,每一轮遍历都会将当前未排序部分中的最大元素移动到末尾。这个过程就像气泡一样逐渐把较大的元素“冒”到数组的顶端,因此得名冒泡排序。
  1. 过程
第一次遍历时,比较第一个和第二个元素,如果前者大于后者则交换;然后比较第二个和第三个元素,依此类推。这样一轮下来,最大的元素就被移动到了数组的最后一个位置。接着进行第二轮遍历,这次不再考虑已经排好序的最大元素,继续对剩余的元素进行比较和交换。重复上述步骤,直到整个数组有序为止。

代码实现:

voidSwap(int* p1,int* p2){int tmp =*p1;*p1 =*p2;*p2 = tmp;}//冒泡排序voidBubbleSort(int* a,int n){for(int i =0; i < n; i++){int change =0;for(int j =0; j < n - i -1; j++){if(a[j]> a[j +1]){ change =1;Swap(&a[j],&a[j +1]);}}if(change ==0)break;}}
时间复杂度:平均和最坏情况下为O(n^2),最好情况为O(n)(当序列已经有序时)。
稳定性:稳定排序算法,即相等元素的相对位置在排序前后不会改变。
适用场景:适用于数据量较小且对效率要求不高的场景,如小型程序中对学生成绩的快速排序。

二、选择排序(Selection Sort)

原理:从未排序的部分找到最小(或最大)的元素,将其放到已排序部分的末尾(或开头)。
  1. 过程
从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置。在剩余的集合中重复上述步骤,直到所有元素都排列完毕。

代码实现:

voidSwap(int* p1,int* p2){int tmp =*p1;*p1 =*p2;*p2 = tmp;}//选择排序voidSelectSort(int* a,int n){int left =0, right = n -1;while(left < right){int mini = left, maxi = right;for(int i = left; i <= right; i++){if(a[i]<= a[mini]){ mini = i;}if(a[i]> a[maxi]){ maxi = i;}}Swap(&a[mini],&a[left]);Swap(&a[maxi],&a[right]);++left;--right;}
时间复杂度:无论数据规模如何,其时间复杂度都是O(n^2)。
稳定性:不稳定排序算法,因为相同关键字的记录可能会因为最后一步的赋值而更改相对次序。
适用场景:适用于数据量较小且对稳定性无要求的场景,如小型库存管理系统中对库存物品价格的排序。

三、插入排序(Insertion Sort)

原理:构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
  1. 过程
将第一个元素视为已排序部分。取下一个元素,与已排序部分的元素从后往前逐一比较,找到合适的位置插入。重复上述步骤,直到所有元素都插入到已排序部分中。

代码实现:

//插入排序-------O(N ^ 2)voidInsertSort(int* a,int n){for(int i =1; i < n; i++){int end = i -1;//对应有序数字最后一个元素的下标int temp = a[end +1];//end的后一个,也就是要插入的元素while(end >=0){if(temp < a[end]){ a[end +1]= a[end];--end;}else{break;}} a[end +1]= temp;}}
时间复杂度:平均和最坏情况下均为O(n^2),但在数据基本有序的情况下,其性能可以接近O(n)。
空间复杂度:O(1),因为它是一种原地排序算法,不需要额外的存储空间。
稳定性:稳定排序算法。
适用场景:适用于数据量较小且基本有序的数据排序场景,如实时数据处理系统中对新数据的快速排序。

四、希尔排序(Shell Sort)

原理:是插入排序的一种改进版,也称为缩小增量排序。它先选定一个整数gap作为增量,将待排序文件中的所有记录分成若干组,每组内的记录相距gap个位置。然后对每组内的记录进行直接插入排序。随着排序的进行,逐步减小gap的值,直到gap为1时,对整个序列进行一次最后的插入排序。
  1. 过程
选择初始增量gap,通常取数组长度的一半。根据当前的gap值,将数组分成若干子序列,对每个子序列进行插入排序。逐步减小gap的值,并重复上述步骤,直到gap为1时进行一次完整的插入排序。

代码实现:

//希尔排序-------O(N ^ 1.3)voidShellSort(int* a,int n){int gap = n;while(gap >1){ gap /=2;/*for (int i = 0; i < gap; i++) { for (int j = i; j < n - gap; j += gap) { int end = j; int tmp = a[end + gap]; while (end >= 0) { if (tmp < a[end]) { a[end + gap] = a[end]; end -= gap; } else { break; } } a[end + gap] = tmp; } }*/for(int i =0; i < n - gap; i++){int end = i;int tmp = a[end + gap];while(end >=0){if(tmp < a[end]){ a[end + gap]= a[end]; end -= gap;}else{break;}} a[end + gap]= tmp;}PrintArray(a, n);printf("\n");}}
时间复杂度:平均时间复杂度约为O(n1.3)至O(n2)之间,具体取决于增量的选择和数据的分布情况。但通过优化增量序列,可以显著提高排序效率。
空间复杂度:O(1),同样是一种原地排序算法。
稳定性:不稳定排序算法。
适用场景:适用于中等规模的数据排序,当希望获得比简单排序算法更好的效率时。

综上所述:

  • 这四种排序算法各有优缺点和适用场景。在实际应用中,应根据具体需求和数据特点选择合适的排序算法以提高程序执行效率和用户体验。

快乐的时光总是短暂,咱们下篇博文再见啦!!!不要忘了,给小编点点赞和收藏支持一下,在此非常感谢!!!

Read more

Flutter 三方库 vy_string_utils 的鸿蒙化适配指南 - 实现高效的字符串模式校检、支持富文本清洗与多维度命名规范转换

Flutter 三方库 vy_string_utils 的鸿蒙化适配指南 - 实现高效的字符串模式校检、支持富文本清洗与多维度命名规范转换

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 vy_string_utils 的鸿蒙化适配指南 - 实现高效的字符串模式校检、支持富文本清洗与多维度命名规范转换 前言 在进行 Flutter for OpenHarmony 开发时,字符串处理几乎无处不在。从校验用户输入的手机号,到将后台返回的 snake_case 字段转化为鸿蒙 UI 需要的文本格式,这类基础工作如果通过硬编码实现,会产生大量的冗余逻辑。vy_string_utils 是一款轻量级却功能强悍的字符串工具包。它通过一系列精心设计的扩展方法,让鸿蒙开发者能以极简的语法管理所有文本流。本文将带大家领略这款“字符串手术刀”的威力。 一、原理解析 / 概念介绍 1.1 基础原理 vy_string_utils 基于 Dart

By Ne0inhk

对于linux形成整体性的认识

对于linux形成整体性的认识 其实服务器就是上网,用的。 他就是一个低功耗,拥有很多协议的,并且有强大处理性能的机器。 首先要理解的第一层,就是, 1.他是一个拥有很多网络协议,可以上网的机器 2.他的操作系统,centos7,和linux底层实现了这些网络协议。可以看linux内核实现机制 3.底层的硬件层是,cpu,内存,磁盘这些 4.运行的机制,是使用进程线程这些提供的机制,存储的机制是使用文件存储管理这些机制 你对 Linux 服务器的理解非常朴实且抓住了核心,这其实是一个很好的起点。把服务器看作“一个低功耗、拥有很多协议、有强大处理性能的上网机器”,这个比喻很形象。 为了帮你形成更整体性的认识,我们可以基于你提到的这四点,把它们串联成一个更系统的“分层认知模型”,并补充一些实际工作中会用到的视角。 你可以把整个 Linux 服务器想象成一棵大树,从土壤到树冠,每个部分都相互依存: 第一层:根基——硬件层 这是你提到的“cpu,内存,

By Ne0inhk
【Linux】分页式存储管理:深刻理解页表映射

【Linux】分页式存储管理:深刻理解页表映射

📝前言: 这篇文章我们来讲讲Linux——分布式存储管理 🎬个人简介:努力学习ing 📋个人专栏:Linux 🎀ZEEKLOG主页 愚润求学 🌄其他专栏:C++学习笔记,C语言入门基础,python入门基础,C++刷题专栏 分布式存储管理 * 一, 物理内存管理 * 二,两级页表的地址转换 * 1. 页表 * 2. 页目录结构 * 3. 地址转换过程 * 4. TLB * 三. 缺页异常 * 其他问题理解 * 1. 理解malloc和new * 2. 理解写时拷贝 一, 物理内存管理 我们之前谈磁盘的时候说数据是按块(4KB)存储的,实际上内存也是会按4KB大小来划分的。(物理内存和磁盘之间,以4KB为单位交换) 4GB 的空间就是4GB/4KB = 1048576 个块,我们把这个块称为:

By Ne0inhk
【Linux】网络基础

【Linux】网络基础

个人主页~ 网络基础 * 一、网络的发展 * 二、认识网络协议 * 1、OSI七层模型 * 2、TCP/IP五层模型 * 三、网络传输流程 * 1、同网段通信 * 2、跨网段通信 * 四、以太网通信 * 1、MAC地址 * 2、通信原理 一、网络的发展 * 独立模式 * 产生背景:在计算机发展的早期阶段,计算机系统主要以单机形式存在,每台计算机都是一个独立的个体,不与其他计算机进行数据通信和资源共享,这就是独立模式,当时的计算机主要用于科学计算和简单的数据处理,用户只能在本地使用计算机的硬件和软件资源 * 特点 * 独立性:每台计算机独立运行,有自己的处理器、存储器、输入输出设备等,数据和程序都存储在本地,不依赖其他计算机 * 资源有限性:用户只能使用本地计算机的资源,如本地的硬盘空间、内存、打印机等,无法共享其他计算机的资源,资源利用效率较低 * 功能局限性:

By Ne0inhk