【408篇】C语言笔记-第十七章(考研必会的排序算法(下))

news2024/11/16 11:35:17

文章目录

    • 第一节:选择排序
      • 1. 选择排序原理解析
      • 2. 选择排序代码实战
      • 3. 时间复杂度与空间复杂度
    • 第二节:堆排序
      • 1. 堆排序原理解析
      • 2. 堆排序代码实战
      • 3. 时间复杂度与空间复杂度
    • 第三节:归并排序
      • 1. 归并排序原理解析
      • 2. 归并排序代码实战
      • 3. 时间复杂度与空间复杂度
    • 第四节:小结
      • 所有排序算法时间与空间复杂度汇总

第一节:选择排序

1. 选择排序原理解析

选择排序分为:1.简单选择排序。2.堆排序(重要)。

简单选择排序原理:假设排序表为L[1,2,……n],第i趟排序即从L[i……n]中选择关键字最小的元素与L(i)交换,每一趟排序可以确定一个元素的最终位置,这样经过n-1趟排序就可使得整个排序表有序。

首先嘉定第0个元素是最小的,把下标0赋给min(min记录最小的元素的下标),内层比较时,从1号元素一直比较到9号元素,谁更小,就把它的下标赋给min,一轮比较结束后,将min对应的位置的元素与元素i交换。第一轮确认2最小,将2与数组开头的元素3交换,第二轮我们最初认为87最小,经过一轮比较,发现3最小,将87与3交换。持续进行,最终使数组有序。

动画演示:
https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html

2. 选择排序代码实战

步骤:随机10个元素->打印->选择排序->打印。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef int ElemType;
typedef struct {
    ElemType *elem; // 整型指针
    int TableLen; // 存储动态数组里边元素的个数,相当于之前的len
}SSTable;

// 初始化链表
void ST_Init(SSTable &ST,int len){
    ST.TableLen=len;
    ST.elem= (ElemType*)malloc(sizeof(ElemType)*ST.TableLen);
    int i;
    srand(time(NULL));// 生成随机数
    for(i=0;i<ST.TableLen;i++){
        ST.elem[i]=rand()%100; // 为了让随机数在0-99之间
    }
}
// 打印
void ST_print(SSTable ST){
    for(int i=0;i<ST.TableLen;i++){
        printf("%3d",ST.elem[i]);// 和获取数组方法一样
    }
    printf("\n");
}
// 交换位置
void swap(ElemType &a,ElemType &b){
    ElemType tmp;
    tmp=a;
    a=b;
    b=tmp;
}
// 选择排序
void SelectSort(ElemType A[],int n){
    int i,j,min;
    for(i=0;i<n-1;i++){
        min=i; // 认为第i个位置最小
        for(j=i+1;j<n;j++){
            if(A[j]<A[min]){
                min=j;
            }
        }
        if(min!=i){
            swap(A[i],A[min]);
        }
    }
}
int main() {
    SSTable ST;
    ST_Init(ST,10);
    ST_print(ST);
    SelectSort(ST.elem,10);
    ST_print(ST);
    return 0;
}
F:\Computer\Project\practice\17\17.3-selectSort\cmake-build-debug\17_3_selectSort.exe
  5  8 65 13 26 38 40 65 82 97
  5  8 13 26 38 40 65 65 82 97

进程已结束,退出代码为 0

3. 时间复杂度与空间复杂度

时间复杂度O( n 2 n^2 n2)。

空间复杂度O(1)。

第二节:堆排序

1. 堆排序原理解析

堆(Heap)是计算机科学中的一种特殊的树状数据结构。若满足以下特性,则可称为堆:“给定堆中任意节点P和C,若P是C的父结点,则P的值小于等于(或大于等于)C的值。”若父结点的值恒小于等于子结点的值,则该堆称为最小堆(min heap),反之,称为最大堆(max heap)。堆中最顶端的那个结点称为根结点(root node),根结点本身没有父结点(parent node)。平时工作中,我们将最小堆称为小根堆或小顶堆,把最大堆称为大根堆或大顶堆。

假设我们有3,87,2,93,78,56,61,38,12,40共10个元素,我们将这10个元素建成一棵完全二叉树,这里采用层次建树法,虽然只有一个数组存储元素,但是我们能将二叉树中任意一个位置的元素对应到数组下标上,我们将二叉树中每个元素到数组下标的这种数据结构称为堆。比如最后一个父元素的下标是n/2-1,也就是a[4],对应的值是78。可以这样记忆:如果父结点的下标是dad,那么父结点对应的左子结点的下标值是2*dad+1。接着,依次将没棵子树都调整为父结点最大,最终整棵树将变成一个大根堆。

动画演示:
https://www.cs.usfca.edu/~galles/visualization/HeapSort.html

2. 堆排序代码实战

堆排序的步骤是首先把堆调整为大根堆,然后我们交换根部元素也就是A[0]和最后一个元素,这样最大的元素就放到了数组最后,接着我们将剩余9个元素继续调整成大根堆,然后交换A[0]和9个元素最后一个,循环往复,直到有序。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

typedef int ElemType;
typedef struct {
    ElemType *elem; // 整型指针
    int TableLen; // 存储动态数组里边元素的个数,相当于之前的len
}SSTable;

// 初始化链表
void ST_Init(SSTable &ST,int len){
    ST.TableLen=len;
    ST.elem= (ElemType*)malloc(sizeof(ElemType)*ST.TableLen);
    int i;
    srand(time(NULL));// 生成随机数
    for(i=0;i<ST.TableLen;i++){
        ST.elem[i]=rand()%100; // 为了让随机数在0-99之间
    }
}
// 打印
void ST_print(SSTable ST){
    for(int i=0;i<ST.TableLen;i++){
        printf("%3d",ST.elem[i]);// 和获取数组方法一样
    }
    printf("\n");
}
// 交换位置
void swap(ElemType &a,ElemType &b){
    ElemType tmp;
    tmp=a;
    a=b;
    b=tmp;
}

// 调整子树
void AdjustDown(ElemType A[],int k,int len){
    int dad=k;
    int son=2*dad+1; // 左孩子下标
    while (son<=len){
        if(son+1<=len&&A[son]<A[son+1]){ // 看下有没有右孩子,比较左右选孩子大的
            son++;
        }
        if(A[son]>A[dad]){ // 孩子和父亲比较,如果孩子大于父亲,那么进行交换
            swap(A[son],A[dad]);
            dad=son; // 孩子重新最为父亲,判断下一棵子数是否符合大根堆
            son=2*dad+1;
        } else{
            break;
        }
    }
}
// 堆排序
void HeapSort(ElemType A[],int len){
    int i;
    // 建立大根堆
    for(i=len/2;i>=0;i--){
        AdjustDown(A,i,len);
    }
    swap(A[0],A[len]);// 交换顶部和数组最后一个元素
    // 下面的策略是,不断调整剩余元素为大根堆,因为根部最大,所以再次与A[i]交换,相当于放数组后面,循环往复
    for(i=len-1;i>0;i--){
        AdjustDown(A,0,i);// 剩余元素调整为大根堆
        swap(A[0],A[i]);
    }
}
int main() {
    SSTable ST;
    ST_Init(ST,10);
    ElemType A[10]={3,87,2,93,78,56,61,38,12,40};
    memcpy(ST.elem,A, sizeof(A));
    ST_print(ST);
    HeapSort(ST.elem,9); // 所有元素参与排序
    ST_print(ST);
    return 0;
}
F:\Computer\Project\practice\17\17.5-heapSort\cmake-build-debug\17_5_heapSort.exe
  3 87  2 93 78 56 61 38 12 40
  2  3 12 38 40 56 61 78 87 93

进程已结束,退出代码为 0

3. 时间复杂度与空间复杂度

第三节:归并排序

1. 归并排序原理解析

如图所示,我们把每两个元素归为一组,进行小组内排序,然后再次把两个有序小组合并为一个有序小组,不断进行,最终合并为一个有序数组。

动画演示:
https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html

2. 归并排序代码实战

归并排序的代码是采用递归思想实现的。首先,最小下标值和最大下标值相加并除以2,得到中间下标值mid,用MergeSort对low到mid排序,然后用MergeSort对mid+1到high排序。当数组的前半部分和后半部分都排好序,使用Merge函数对两个有序数组进行合并。为了提高合并有序数组效率,在Merge函数内定义了B[N]。首先,我们通过循环把数组A中从low到high的元素全部复制到B中,这是游标i从low开始,游标j从mid+1开始,谁小就将谁放入数组A,对其游标加1,并在每轮循环时对数组A的计数游标k加1。

#include <stdio.h>
#include <stdlib.h>

#define N 7
typedef int ElemType;
// 49,38,65,97,76,13,27

// 合并数组
void Merge(ElemType A[],int low,int mid,int high){
    static ElemType B[N]; // 加static的目的是无论递归调用多少次,都只有一个B[N]
    int i,j,k;
    for(k=low;k<=high;k++){ // 赋值元素到B中
        B[k]=A[k];
    }
    for(i=low,j=mid+1,k=i;i<=mid&& j<=high;k++){ // 合并两个有序数组
        if(B[i]<=B[j]){
            A[k]=B[i++];
        } else{
            A[k]=B[j++];
        }
    }
    while (i<=mid){ // 如果右剩余,直接放入即可
        A[k++]=B[i++]; // 前一半有剩余的放入
    }
    while (j<=high){
        A[k++]=B[j++];//后一半的有剩余的放入
    }
}
// 归并排序
void MergeSort(ElemType A[],int low,int high){
    if(low<high){
        int mid=(low+high)/2;
        MergeSort(A,low,mid); // 排序前一半
        MergeSort(A,mid+1,high); // 排序后一半
        Merge(A,low,mid,high); // 将两个排序好的数组合并
    }
}

// 打印
void print(int *a){
    for(int i=0;i<N;i++){
        printf("%3d",a[i]);
    }
    printf("\n");
}
int main() {
    int A[7]={49,38,65,97,76,13,27}; // 数组,7个元素
    print(A);
    MergeSort(A,0,6);
    print(A);
    return 0;
}
F:\Computer\Project\practice\17\17.6-mergeSort\cmake-build-debug\17_6_mergeSort.exe
 49 38 65 97 76 13 27
 13 27 38 49 65 76 97

进程已结束,退出代码为 0

3. 时间复杂度与空间复杂度

第四节:小结

所有排序算法时间与空间复杂度汇总

稳定性是指排序前后,相等元素位置是否会被交换。

复杂性是指代码编写的难度。

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

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

相关文章

5、前端笔记-JS-运算符

运算符也被称为操作符&#xff0c;用于实现赋值、比较和执行算数运算等功能的符号 常用的运算符&#xff1a; 算数运算符、递增和递减运算符、比较运算符、逻辑运算符、赋值运算符 1、算术运算符 -*/% - * / %&#xff08;1&#xff09;%取余可以用来判断一个数是否可以被整除…

家政清洁服务系统设计与实现

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 修改意见&#xff1a;题目改为“家政清洁服务系统设计与实现” 提供服务&#xff1a;钟点打扫卫生&#xff08;按小时收…

node.js+uni计算机毕设项目基于微信平台的大学生时间规划管理小程序设计(程序+小程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等…

二次封装a-upload组件,自定义上传预览

a-upload封装效果自定义上传customRequesttransformFile上传前修改文件流自定义预览调整props和a-uoload一致install封装vue组件结束效果 编辑 预览 不展示删除和上传 空数据 自定义图片样式 自定义上传customRequest 入参是本地上传的文件流 async customRequest(file) …

Java笔记之线程池详解

文章目录一、线程池是什么&#xff1f;二、为什么要使用线程池&#xff1f;三、jdk自带的四种线程池1. 线程池参数2.工作队列3.拒绝策略4.四种线程池一些示例四、自定义线程池一、线程池是什么&#xff1f; 一种线程使用模式&#xff0c;是一种多线程处理形式&#xff0c;处理…

FineReport表格软件-CSS动态切换年月日查询报表

1. 概述 1.1 版本 报表服务器版本 功能变更 11.0 -- 1.1 预期效果 由于业务的需要&#xff0c;很多情况下需要当满足某个条件时&#xff0c;某些查询条件才显示出来&#xff0c;如下图所示&#xff1a; 1.2 实现思路 由于业务的需要&#xff0c;很多情况下需要当满足某个…

[Flask]环境配置和项目框架的构建

一、配置flask 在Python环境下使用控制台的pip install命令进行安装 pip install Flask2.1.0 &#xff01;&#xff01;&#xff01;安装版本必须是2.x以上&#xff0c;否则可能出现错误&#xff1a;cannot import name escape from jinja2 &#xff08;flask 2.x放弃了对jinj…

CloudCompare 的简单的使用说明

File open&#xff1a;打开 save&#xff1a;保存 Global Shift settings&#xff1a;设置最大绝对坐标&#xff0c;最大实体对角线 Primitive Factory&#xff1a;对点云进行原始加工&#xff0c;改变原始点云的形状 3D mouse&#xff1a;对3D鼠标&#xff08;如3Dconnexion&a…

二叉树的绘制

目录 一、知乎方法 二、动手实践 DOT 语言 无向图 有向图 绘制二叉树 设置属性 如何绘制优美的二叉树 一、知乎方法 知乎上的大佬提供了一系列画图的方法&#xff0c;感兴趣的朋友可以自行去看看 用 Graphviz 绘制一棵漂亮的二叉树 - 南浦月 二叉搜索树&#xff0c…

庖丁解牛式讲解并发编程,GitHub高星最新开源阿里Java进阶必备手册

最近看到粉丝群里讨论最多的问题是现在Java这么卷&#xff0c;担心年龄大了以后会被裁员或者清退&#xff0c;要怎么做才能保住自己的“饭碗”。楼主认为不论是阅读优秀源码、领略设计思路&#xff0c;还是学习优秀架构、代码设计等等&#xff0c;都是加薪升职的正确路径&#…

安全分析开发环境 技术背景

安全分析开发环境一键部署 Gartner 报告中指出 [7]&#xff0c;Platfor m Ops for AI 是一种编排和扩展运营人工智能的方法&#xff0c;利用跨数据、机器学习、人工智能和应用程序 开发管道的多种最佳实践&#xff0c;为基于人工智能的系统创建一个高效的交付模型。Platform O…

RV1126笔记十七:吸烟行为检测及部署<四>

若该文为原创文章&#xff0c;转载请注明原文出处。 转换成onnx模型(windows) 一、查看pt文件 准备好训练好的pt文件,可以用Netron打开看看大概长啥样: 二、模型转换 主要的目的是想把训练好的pt文件转成onnx模型&#xff0c;为后面RV1126的部署做铺垫。 我们是在py38的con…

ChatGPT怎么突然变得这么强?华人博士万字长文深度拆解GPT-3.5能力起源

文章目录一、2020 版初代 GPT-3 与大规模预训练二、从 2020 版 GPT-3 到 2022 版 ChatGPT三、Code-Davinci-002和 Text-Davinci-002&#xff0c;在代码上训练&#xff0c;在指令上微调四、text-davinci-003 和 ChatGPT&#xff0c;基于人类反馈的强化学习的威力五、总结当前阶段…

SAP MM SPED输出报错-No authorization for delivery from shipping point US##-之对策

SAP MM SPED输出报错-No authorization for delivery from shipping point US##-之对策 前日收到某客户业务人员上报的一个问题&#xff0c;说是发现某个公司间STO单据的外向交货单里SPED 这个output不成功&#xff0c;不能成功触发inbound delivery单据。 相关报错信息如下&am…

项目实战之旅游网(四)后台角色管理(上)

目录 一.角色列表 二.新增角色 三.修改角色 四.删除角色 一.角色列表 接下来我们编写角色管理功能&#xff0c;首先查询角色列表: 1.编写RoleService Service public class RoleService {Autowiredprivate RoleMapper roleMapper;public Page<Role> findPage(int …

【无线通信】鲸鱼优化算法及其在无线网络资源分配中的应用(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

腾讯云Linux 轻量应用服务器如何搭建 FTP 服务?

Vsftpd&#xff08;very secure FTP daemon&#xff09;是众多 Linux 发行版中默认的 FTP 服务器。本文以 CentOS 7.6 64位操作系统的轻量应用服务器为例&#xff0c;使用 vsftpd 软件搭建 Linux 轻量应用服务器的 FTP 服务。 本文搭建 FTP 服务组成版本如下&#xff1a; Lin…

node.js+uni计算机毕设项目基于微信点餐系统小程序(程序+小程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等…

Allegro如何设置格点操作指导

Allegro如何设置格点操作指导 在PCB设计的时候,格点是一个很好用的工具,Allegro可以设置格点 具体操作如下 选择Setup-GirdsNon-Etch和All Etch中的X和Y都输入5,代表都是5的格点

CTF-MISC(入门|笔记|工具)

文章目录音频隐写直接隐写频谱隐写流量分析第一种流量包修复第二种是协议分析第三种数据提取图片分析zstegBMPPNGforemost 工具binwalksteghidestegslovetweakpngJPGF5-steganographystegdetect压缩包分析zip伪加密crc32zip包明文攻击其它条形码扫描pyc反编译数据转换到ASCII乱…