数据结构(七)递归、快速排序

文章目录

  • 一、递归
    • (一)使用递归实现1~n求和
      • 1. 代码实现:
      • 2. 调用过程:
      • 3. 输出结果:
    • (二)青蛙跳台阶问题
      • 1. 问题分析
      • 2. 代码实现
      • 3. 输出结果
      • 4. 代码效率优化
      • 5. 优化后的输出结果
  • 二、快速排序
    • (一)概念
    • (二)基本思想
    • (三)排序流程
    • (三)代码实现

一、递归

递归就是在函数内部继续调用自身的逻辑。

注:

  1. 递归的本质就是函数调用,他并不是C语言程序结构的一种。
    C语言的程序结构只有三种:循序结构、分支(选择)结构、循环结构
  2. 每个递归必须有一个出口,否则函数无限次调用下去,会把内存资源耗尽,导致堆栈溢出,出现段错误

(一)使用递归实现1~n求和

1. 代码实现:

#include <stdio.h>

//计算 1~n 的求和结果 并返回
int my_sum(int n){
    if(1 == n) return 1;
    return my_sum(n-1) + n;
}

int main(int argc, char const *argv[])
{
    int ret = my_sum(100);
    printf("sum = %d\n", ret);
    return 0;
}

2. 调用过程:

以n=5为例,
首先在main函数中调用my_sum(5)
my_sum(5)的返回值是my_sum(4)+n,
因此会继续调用my_sum(4),my_sum(4)的返回值是my_sum(3)
继续调用my_sum(3),my_sum(3)的返回值是my_sum(2)
继续调用my_sum(2),my_sum(2)的返回值是my_sum(1)
当n==1时,即是递归函数的出口,返回1给my_sum(2),
my_sum(2)的返回值即是2+1=3,返回3给my_sum(3),
my_sum(3)的返回值是3+3=6,返回6给my_sum(4),
my_sum(4)的返回值就是6+4=10,返回10给my_sum(5),
最后得到my_sum(5)的结果就是10+5=15,返回15给main函数。

3. 输出结果:

在这里插入图片描述

(二)青蛙跳台阶问题

共有10阶台阶,青蛙每次只能跳1阶或者2阶
问:青蛙跳上这10阶台阶,共有多少种跳法?

1. 问题分析

跳上10阶台阶的方法等于从第8阶台阶跳上10阶和从第9阶台阶跳上10阶的方法之和,跳上9阶台阶的方法等于从第8阶台阶和从第7阶台阶跳上9阶的方法之和,然后依次类推…
当计算跳上1阶台阶的方法时,就是1种,跳上2阶台阶的方法就是2种,这时就是递归函数的出口

2. 代码实现

#include <stdio.h>

//定义一个全局变量用于记录函数调用次数
int count = 0;
//功能:计算跳上n阶台阶的跳法之和 返回计算的结果
int func(int n){
    count++;
    //递归的出口
    if(1 == n) return 1;
    if(2 == n) return 2;
    return func(n-1) + func(n-2);
}

int main(int argc, const char *argv[])
{
    int ret = 0;
    ret = func(10);
    printf("ret = %d\n", ret);
    printf("count=%d\n",count);
    return 0;
}

3. 输出结果

在这里插入图片描述

4. 代码效率优化

如果只是用递归,会有大量重复运算,效率会比较低
可以以空间换时间,保存已经计算过的值来提高效率

#include <stdio.h>

#define NUM_JUMP 10 //台阶数量
//定义一个全局变量用于记录函数调用次数
int count = 0;
//定义一个数组用于保存调用函数的值,保存跳上每阶台阶的方法
int sum[NUM_JUMP]={0};//数组的值全部初始化为0

int my_jump(int n){
    count++;
    if(n==1) return 1;
    if(n==2) return 2;
    if(sum[n]) return sum[n]; //当sum[n]不为空时,说明已经计算过该值,可以直接返回
    //如果sum[n]==0时,说明该值没计算过,计算该值并保存到sum数组中
    sum[n]=my_jump(n-1)+my_jump(n-2);
    return sum[n];
}

int main(int argc, char const *argv[])
{
    int ret = my_jump(10);
    printf("jump = %d\n", ret);//89
    printf("count = %d\n",count);
    return 0;
}

5. 优化后的输出结果

在这里插入图片描述
可见优化后的函数调用次数远远小于优化前的函数调用次数,牺牲部分空间换来效率的提高

二、快速排序

(一)概念

快速排序相当于对冒泡排序的一个优化,也是基于交换的排序算法
时间复杂度 O(nlogn)

(二)基本思想

通过一趟排序,将待排序数据分成两部分,其中一部分数据都比另一部分小,而这两部分数据的内部不要求有序;
然后再对这两部分数据做同样的操作,也各自分成一大一小两部分,依次类推,直到整个数据组有序

(三)排序流程

定义两个下标变量,分别指向待排序的数组段的头和尾
以下图为例:
在这里插入图片描述
定义一个flag变量记录左侧第一个元素flag=arr[low](为了编程方便,也可以记录右侧第一个元素),然后从右向左开始依次比较flag和数组元素的大小
注:此处不要写成flag=arr[0]; 因为之后要对左右半边分别递归使用该函数,当对右半边排序时,应该使flag等于右半边的最左侧的数
如果flag<arr[high],就执行high- -,即下标high向左移动
在这里插入图片描述
如果flag>arr[high],就执行arr[low]=arr[high],low++,但是前提条件是low<high
在这里插入图片描述
此时再从左往右依次比较flag和arr[low]的大小
如果flag>arr[low],就执行low++
在这里插入图片描述
如果flag<arr[low],就执行arr[high]=arr[low],high- -,但是前提条件是low<high
在这里插入图片描述

循环上述两个步骤直到low==high时,将arr[low]=flag或者arr[high]=flag
此时flag左边都是比flag小的数,flag右边都是比flag大的数,但是两侧无序
在这里插入图片描述
之后再对左半边和右半边分别排序
此处仅以右半边为例,左半边同理,只是low和high的值不同。
右半边:low=5,high=9(左半边:low=0,high=3)
在这里插入图片描述
首先使flag=arr[low],此处为7
然后判断flag<arr[high]? 如果小于,就执行high- -
在这里插入图片描述

如果大于就执行arr[low]=arr[high],low++
在这里插入图片描述
之后判断flag>arr[low]? 如果大于,就执行low++
如果小于就执行arr[high]=arr[low],high- -
在这里插入图片描述
直到low==high时,arr[low]=flag或者arr[high]=flag
在这里插入图片描述
左半边同理,此处不再赘述。

(三)代码实现

#include <stdio.h>

int print(int *arr,int len){
    if(NULL==arr) return -1;
    for(int i=0;i<len;i++){
        printf("%d ",arr[i]);
    }
    putchar(10);
    return 0;
}

int my_sort(int *arr,int low,int high){
    if(NULL==arr) return -1;
    int flag=arr[low];
    while(low < high){
        while(flag<arr[high]&&low<high){
            high--;
        }
        if(low<high){
            arr[low]=arr[high];
            low++;
        }
        while(flag>arr[low]&&low<high){
            low++;
        }
        if(low<high){
            arr[high]=arr[low];
            high--;
        }
    }
    arr[low]=flag;
    return low;
}

int quick_sort(int *arr,int low,int high){
    if(NULL==arr) return -1;
    if(low < high){
        int ret=my_sort(arr,low,high);
        quick_sort(arr,low,ret-1);
        quick_sort(arr,ret+1,high);
    }
    return 0;
}

int main(int argc, char const *argv[]){
    int arr[10]={5,2,3,10,7,1,4,9,6,8};
    printf("排序前:\n");
    print(arr,10);

    printf("排序后:\n");
    quick_sort(arr,0,9);
    print(arr,10);
    
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL进阶之(九)数据库的设计规范

九、数据库的设计规范 9.1 范式的概念9.1.1 范式概述9.1.2 键和相关属性 9.2 常见的范式9.2.1 第一范式9.2.2 第二范式9.2.3 第三范式9.2.4 第四范式9.2.5 第五范式&#xff08;域键范式&#xff09; 9.3 反范式化9.3.1 概述9.3.2 举例9.3.3 反范式化新问题9.3.4 通用场景 9.4 …

互联网的利

在互联网没发明之前&#xff0c;人类说话要近距离的说&#xff0c;玩游戏要近距离的玩&#xff0c;十分麻烦。于是&#xff0c;互联网解决了这个问题。聊天可以在电脑上聊&#xff0c;玩游戏可以用游戏软件查找玩家来玩&#xff0c;实现了时时可聊&#xff0c;时时可玩的生活。…

K210 数字识别 笔记

一、烧写固件 连接k210开发板&#xff0c;点开烧录固件工具&#xff0c;选中固件&#xff0c;并下载 二、模型训练 网站&#xff1a;MaixHub 1、上传文件 2、开始标记数据 添加9个标签&#xff0c;命名为1~9&#xff0c;按键盘w开始标记&#xff0c;键盘D可以下一张图片&…

NLP技术发展和相关书籍分享

自然语言处理&#xff08;Natural Language Processing&#xff0c;NLP&#xff09;是计算机科学领域和人工智能领域的重要研究方向之一&#xff0c;旨在探索实现人与计算机之间用自然语言进行有效交流的理论与方法。它融合了语言学、计算机科学、机器学习、数学、认知心理学等…

装机必备——Bandizip7.33安装教程

装机必备——Bandizip7.33安装教程 软件下载 软件名称&#xff1a;Bandizip7.33 软件语言&#xff1a;简体中文 软件大小&#xff1a;8.42M 系统要求&#xff1a;Windows7或更高&#xff0c; 64位操作系统 硬件要求&#xff1a;CPU2GHz &#xff0c;RAM4G或更高 下载通道①迅…

Nature Communications 南京大学开发智能隐形眼镜用于人机交互

近日&#xff0c;南京大学的研究人员研制了一种微型、难以察觉且生物相容的智能隐形眼镜&#xff08;smart contact lenses &#xff0c;SCL&#xff09;&#xff0c;可用于原位眼球追踪和无线眼机交互。采用频率编码策略&#xff0c;无芯片、无电池的镜头成功地检测眼球运动和…

机器学习之聚类学习

聚类算法 概念 根据样本之间相似性&#xff0c;将样本划分到不同类别种&#xff0c;不同相似度计算方法&#xff0c;会得到不同聚类结果&#xff0c;常用相似度计算方法为&#xff1a;欧氏距离 目的是在没有先验知识情况下&#xff0c;自动发现数据集种内在结构和模式 无监督…

告别裸奔,聊聊主流消息队列的认证和鉴权!

大家好&#xff0c;我是君哥。 我们在使用消息队列时&#xff0c;经常关注的是消息队列收发消息的功能。但好多时候需要对客户端有一定的限制&#xff0c;比如只有持有令牌的客户端才能访问集权&#xff0c;不允许 Producer 发送消息到某一个 Topic&#xff0c;或者某一个 Top…

Spring源码编译常见问题解决方案

Spring源码编译常见问题 gradle下载太慢 使用镜像下载。 在gradle-wrappert.prtopertties文件中&#xff0c;将distributionUrl的值修改为镜像地址&#xff0c;这里使用了腾讯的gtrale镜像。 distributionUrlhttps\://mirrors.cloud.tencent.com/gradle/gradle-7.5.1-bin.zi…

H4022 12V24V36V40V4A同步降压芯片 Buck-DCDC 高效率95%

H4022 40V4A同步降压芯片是一款Buck-DCDC转换器&#xff0c;其高效率、高稳定性。以下是对该产品的详细分析&#xff1a; 一、产品优势 高效率&#xff1a;H4022的转换效率高达95%&#xff0c;这主要得益于其同步降压技术。同步降压技术相较于传统的异步降压技术&#xff0c;能…

区块链系统开发测试----链码部署开发、系统开发验证

一.检查配置环境 检查虚拟机环境&#xff0c;确保有正在运行的Hyperledger Fabric区块链&#xff0c;并且其中chaincode_basic、credit_chaincode链码可以正常调用 查看chaincode_basic、credit_chaincode链码调用 二.开发征信链码代码 基于现有征信链码&#xff0c;开发征信…

Debug-012-el-popover 使用 doClose() 关闭窗口不生效的处理方案

前言&#xff1a; 今天上午碰见一个非常奇怪的情况&#xff1a;一样的方法实现的功能&#xff0c;效果却不一样。 两个页面都是使用的doClose()去关闭的el-popover&#xff0c;其中有一个就是不生效&#xff0c;找不同找了半天&#xff0c;始终不得其解。请看效果吧&#xff1…

百度页面奔跑的白熊html、css

一、相关知识-动画 1.基本使用&#xff1a;先定义再调用 2. 调用动画 用keyframes定义动画&#xff08;类似定义类选择器&#xff09; keyframes动画名称{ 0%{ width:100px&#xff1b; } 100%{ width:200px; } } 使用动画 div { width:200px; height:200px; background-…

从华为云Redis到AWS ElastiCache的操作方法

越来越多企业选择出海&#xff0c;那么就涉及到IT系统的迁移&#xff0c;本文将详细介绍如何将华为云Redis顺利迁移到AWS ElastiCache的操作方法&#xff0c;九河云将为您介绍迁移步骤以帮助您顺利完成这一重要任务。 **1. 确定迁移计划** 在开始迁移之前&#xff0c;首先要制…

身为UI设计老鸟,不学点3D,好像要被潮流抛弃啦,卷起来吧。

当前3D原则在UI设计中运用的越来越多&#xff0c;在UI设计中&#xff0c;使用3D元素可以为界面带来以下几个价值&#xff1a; 增强视觉冲击力&#xff1a;3D元素可以通过立体感和逼真的效果&#xff0c;为界面增添视觉冲击力&#xff0c;使得设计更加生动、吸引人&#xff0c;并…

在VS Code中进行Java的单元测试

在VS Code中可以使用 Test Runner for Java扩展进行Java的测试执行和调试。 Test Runner for Java的功能 Test Runner for Java 结合 Language Support for Java by Red Hat 和 Debugger for Java这两个插件提供如下功能&#xff1a; 运行测试&#xff1a; Test Runner for …

protobuf —— 快速上手

protobuf —— 快速上手 创建 .proto 文件添加注释指定proto3语法package 声明符定义消息&#xff08;message&#xff09; 定义消息字段字段定义基本格式字段名称命名规范字段类型字段唯一编号示例 转换关系示例&#xff1a;增加姓名和年龄字段 字段唯一编号字段编号范围编码效…

短视频真人配音:成都科成博通文化传媒公司

短视频真人配音&#xff1a;情感传递的新维度 随着数字化媒体的飞速发展&#xff0c;短视频已经成为人们日常生活中不可或缺的一部分。而在这个视觉盛宴的时代&#xff0c;真人配音的加入为短视频注入了新的活力&#xff0c;不仅丰富了内容形式&#xff0c;更使得情感传递达到…

Oracle EBS API创建AP发票报错:ZX_TAX_STATUS_NOT_EFFECTIVE和ZX_REGIME_NOT_EFF_IN_SUBSCR-

背景 由创建国外业务实体财务未能提供具体国家地区会计税制&#xff0c;而是实施人员随便选择其它国外国家地区会计税制。导致客户化创建AP发票程序报错&#xff1a;UNEXPECTED TAX ERROR-导入时出现意外的税务错误ZX_TAX_STATUS_NOT_EFFECTIVE-ZX_REGIME_NOT_EFF_IN_SUBSCR-ZX…

基于双向长短期记忆BiLSTM对消费者投诉进行多类分类

前言 系列专栏:【深度学习:算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域,讨论了各种复杂的深度神经网络思想,如卷积神经网络、循环神经网络、生成对抗网络、门控循环单元、长短期记…