当前位置: 首页 > news >正文

C语言快速排序(非递归)图文详解

前言:

  上一期分析了快速排序的三种写法,这三种写法有一个相同点,都是采用递归形式来实现的,那么有没有非递归的方法实现呢?答案是当然有,用非递归的方法实现快速排序,其实可以借助数据结构中的栈来模拟实现递归的过程

思路图分析:

  因为使用c语言写的,所以需要我们自己写一个栈,栈的实现我这里不再过多赘述,我会把栈的码放在最后。假如我们现在有下面这组数组,我们要对它进行排序。(注意下面的数字代表下标)

好,接下来开始用栈模拟递归:(图中栈中的数字均表示下标)

1.第一次入栈:

将整个数组入栈,也就是下标为0-8

2.第一次出栈:

每次出栈,对出栈的下标区间进行一次部分排序,这里的部分排序,就是选出key,将其放在正确的位置有3种实现方法,如有不懂可以看我上一期博客,这里我选的是双指针法。第一次出栈进行第一趟部分排序后,数组的元素变为如下图:

此时的key也就是45就被放在了正确的位置,也就是左边的元素都比它小,右边的元素都比它大。

然后再将key的左区间和右区间分别入栈,也就是0-3和5-8

3.第二次出栈:

根据栈的性质后入先出,所以我们让5-8出栈:

跟上面一样,每次出栈对相应区间进行一次部分排序,排序完如下图:

因为在对这个区间进行部分排序时,67被选为key,此时67的右边已经全部比他大,所以排完序后不变,然后再将key的左区间和右区间分别入栈(注意此时的左区间和右区间加起来应该是5-8,因为我们是对5-8这个区间进行部分排序的,而不是0-8),左区间没有元素了也就是4-4,右区间6-8,注意这时候左区间就已经没有必要入栈了(因为少于2个元素必定有序了),只需将没排好序的右区间入栈即可:

4.第二次入栈:

然后只要栈不为空,我们就出栈然后进行和上面一样的操作。

现在就不难感受出,这其实是在模拟递归的过程。

5.第三次出栈:

部分排序后如下图:

跟上面同理左区间少于两个元素不必入栈,右区间入栈7-8

6.第三次入栈:

然后又是7-8出栈,再判断是否入栈,出栈,判断是否入栈,出栈,判断是否入栈一直重复,直到栈里面为空,就排好了,所以循环的使用在这里面也很重要,下面来看一下全部代码吧!

代码:

#include<stdio.h>
#include"Stack.h"void Swap(int* a, int* b)
{int tmp = *a;*a = *b;*b = tmp;
}int PartSort3(int* a, int begin, int end)//双指针法
{int keyi = begin;int prev = begin;int cur = begin + 1;while (cur <= end){if (a[cur] < a[keyi] && ++prev != a[cur]){Swap(&a[cur], &a[prev]);}cur++;}Swap(&a[prev], &a[keyi]);keyi = prev;return keyi;
}void QuickSortNonR(int* a, int begin, int end)
{Stack s;StackInit(&s);StackPush(&s, end);StackPush(&s, begin);//第一次入栈首尾下标while (!StackEmpty(&s))//栈只要不为空,就一直出栈,判断是否入栈......{int left = StackTop(&s);StackPop(&s);int right = StackTop(&s);StackPop(&s);//出栈,首元素下标放在left,尾元素下标放在right,很形象int keyi = PartSort3(a, left, right);//进行一次部分排序,并将最后key的下标返回//[left,keyi-1]keyi[keyi+1,right]//拆分成的区间//下面为判断是否入栈if (left < keyi - 1)//如果左区间元素个数不少于2{StackPush(&s, keyi - 1);StackPush(&s, left);//入栈}if (keyi + 1 < right)//如果右区间元素个数不少于2{StackPush(&s, right);StackPush(&s, keyi+1);//入栈}}//循环结束,栈为空,排序完成StackDestroy(&s);//销毁栈
}

栈的实现代码:

#include"Stack.h"
void StackInit(Stack* ps)//初始化栈
{ps->a = NULL;ps->top = -1;ps->capacity = 0;
}
void StackPush(Stack* ps, STDateType data)//入栈
{StackCheck(ps);ps->top++;ps->a[ps->top] = data;
}
void StackCheck(Stack* ps)//检查容量
{assert(ps);if(ps->top+1==ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDateType* tmp = (STDateType*)realloc(ps->a, sizeof(STDateType) * newcapacity);if (tmp == NULL){perror("realloc");return;}else{ps->a = tmp;ps->capacity = newcapacity;}}
}
bool StackEmpty(Stack* ps)//判空函数
{return ps->top == -1;
}
STDateType StackTop(Stack* ps)//获取栈顶元素
{assert(ps);assert(ps->top+1 > 0);return ps->a[ps->top];
}
void StackPop(Stack* ps)//出栈
{assert(ps);ps->top--;
}
int StackSize(Stack* ps)//获取栈中有效元素的个数
{assert(ps);return ps->top+1;
}
void StackDestroy(Stack* ps)//销毁栈
{assert(ps);free(ps->a);ps->a = NULL;ps->top = -1;ps->capacity = 0;
}

栈的头文件:

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
typedef int STDateType;
typedef struct Stack
{STDateType* a;int top;//栈顶int capacity;//容量
}Stack;
void StackInit(Stack* ps);//初始化栈
void StackCheck(Stack* ps);//检查容量
void StackPush(Stack* ps, STDateType data);//入栈
void StackPop(Stack* ps);//出栈
bool StackEmpty(Stack* ps);//判空函数
STDateType StackTop(Stack* ps);//获取栈顶元素
int StackSize(Stack* ps);//获取栈中有效元素的个数
void StackDestroy(Stack* ps);//销毁栈

相关文章:

C语言快速排序(非递归)图文详解

前言&#xff1a; 上一期分析了快速排序的三种写法&#xff0c;这三种写法有一个相同点&#xff0c;都是采用递归形式来实现的&#xff0c;那么有没有非递归的方法实现呢&#xff1f;答案是当然有&#xff0c;用非递归的方法实现快速排序&#xff0c;其实可以借助数据结构中的栈…...

Java面试题136-150

36、用JDBC如何调用存储过程 代码如下&#xff1a; package com.huawei.interview.lym; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Types; public class JdbcTest…...

使用trace工具分析Mysql如何选择索引

背景说明 工作中,可能会遇到执行一个SQL,明明有索引,但是采用explain分析后发现执行结果并未走索引。甚至还有部分SQL语句相同就只是查询条件不一样也会出现有的走索引,有的不走索引情况。比如: 我的示例环境有个employees表,并有个idx_name_age_position的联合索引…...

微信小程序(十二)在线图标与字体的获取与引入

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.从IconFont获取图标与文字的样式链接 2.将在线图标配置进页面中&#xff08;源码&#xff09; 3.将字体配置进页面文字中&#xff08;源码&#xff09; 4.css样式的多文件导入 获取链接 1.获取图标链接 登入…...

分类预测 | Matlab实现LSTM-Attention-Adaboost基于长短期记忆网络融合注意力机制的Adaboost数据分类预测/故障识别

分类预测 | Matlab实现LSTM-Attention-Adaboost基于长短期记忆网络融合注意力机制的Adaboost数据分类预测/故障识别 目录 分类预测 | Matlab实现LSTM-Attention-Adaboost基于长短期记忆网络融合注意力机制的Adaboost数据分类预测/故障识别分类效果基本描述程序设计参考资料 分类…...

java web mvc-04-Apache Wicket

拓展阅读 Spring Web MVC-00-重学 mvc mvc-01-Model-View-Controller 概览 web mvc-03-JFinal web mvc-04-Apache Wicket web mvc-05-JSF JavaServer Faces web mvc-06-play framework intro web mvc-07-Vaadin web mvc-08-Grails 开源 The jdbc pool for java.(java …...

暴力破解常见的服务器

目录 使用 pydictor 生成自己的字典工具liunx下载使用常用的参数说明插件型字典 (可自己根据 API 文档开发) 使用 hydra 工具在线破解系统用户密码使用 hydra 破解 windows 7 远程桌面密码使用 hydra 工具破解 ssh 服务 root 用户密码 使用 Medusa 工具在线破解medusa参数说明M…...

运行Navicat转储的数据库SQL文件失败

报错&#xff1a;1067 - Invalid default value for ‘publish_date’ 单独拎出来该建表语句执行&#xff0c;报错一样&#xff0c;都是默认值出错 查看该字段的设计语句 publish_date timestamp NOT NULL DEFAULT 0000-00-00 00:00:00 COMMENT 发布时间, 发现该字段的默认值…...

动静态库的理解、制作、使用。

一.动静态库的理解。 1.什么是库&#xff1f; 代码是无穷无尽的&#xff0c;当程序猿在写一些项目时&#xff0c;未必所有代码亲历亲为&#xff0c;他们可以在网上寻找大佬写过的一些有关需求的代码&#xff0c;这些代码可以让他们拿过来直接使用&#xff0c;而省去了许多精力…...

【趣味游戏-08】20240123点兵点将点到谁就是谁(列表倒置reverse)

背景需求&#xff1a; 上个月&#xff0c;看到大4班一个孩子在玩“点兵点将点到谁就是谁”的小游戏&#xff0c;他在桌上摆放两排奥特曼卡片&#xff0c;然后点着数“点兵点将点到谁就是谁”&#xff0c;第10次点击的卡片&#xff0c;拿起来与同伴的卡片进行交换。他是从第一排…...

cherry键盘alt+tab无法切换窗口的问题解决

现象&#xff1a; alt 好用&#xff0c; tab好用&#xff0c;tabalt不好用。 原因&#xff1a; 键盘误触了关闭了alttab的功能。 不同的樱桃键盘可能方法不一样&#xff0c;下面是两个方案&#xff0c;本人的键盘是MX6.0 G80 3930红轴&#xff0c;用的方法一解决就了&#…...

「nuxt2配置tailwindcss」nuxt2添加tailwindcss详细步骤!解决版本不对称各种报错~~

运行环境 node和npm使用版本 node v14.21.3 (npm v6.14.18) 1.插件下载 官方文档说明 npm install -D nuxtjs/tailwindcss3.4.3 tailwindcss3.4.1 postcss^8.4.33 autoprefixer10.4.17 2.nuxt.config.js配置 module.exports {// ...buildModules: [nuxtjs/tailwindcss],// …...

1、中级机器学习课程简介

文章目录 1、课程简介2、先决条件 本课程所需数据集夸克网盘下载链接&#xff1a;https://pan.quark.cn/s/9b4e9a1246b2 提取码&#xff1a;uDzP 1、课程简介 欢迎来到机器学习中级课程&#xff01; 如果你对机器学习有一些基础&#xff0c;并且希望学习如何快速提高模型质量…...

Mybtisplus对时间字段进行自动填充

一、引入依赖 <!-- mybatis-plus-boot-starter--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.2</version></dependency> 二、配置类 这里我…...

[HTML]Web前端开发技术12(HTML5、CSS3、JavaScript )——喵喵画网页

希望你开心&#xff0c;希望你健康&#xff0c;希望你幸福&#xff0c;希望你点赞&#xff01; 最后的最后&#xff0c;关注喵&#xff0c;关注喵&#xff0c;关注喵&#xff0c;佬佬会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的…...

音频特效SDK,满足内容生产的音频处理需求

美摄科技&#xff0c;作为音频处理技术的佼佼者&#xff0c;推出的音频特效SDK&#xff0c;旨在满足企业内容生产中的音频处理需求。这款SDK内置多种常见音频处理功能&#xff0c;如音频变声、均衡器、淡入淡出、音频变调等&#xff0c;帮助企业轻松应对各种音频处理挑战。 一…...

使用vue2写一个太极图,并且点击旋转

下面是我自己写的一个代码&#xff0c;命名有些不规范&#xff0c;大家不要介意。 <template><div class"qq"><div class"app" :style"{ transform: rotateStyle }"><div class"app1"><div class"ap…...

张量计算和操作

一、数据操作 1、基础 import torchx torch.arange(12) # x:tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])x.shape # torch.Size([12])x.numel() # 12x x.reshape(3, 4) # tensor([[ 0, 1, 2, 3], # [ 4, 5, 6, 7], # [ 8, 9, 10, 11]])torch.zeros((2…...

【Spring Boot 3】【JPA】枚举类型持久化

【Spring Boot 3】【JPA】枚举类型持久化 背景介绍开发环境开发步骤及源码工程目录结构总结背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术总是要花…...

SVN 常用命令汇总(2024)

1、前言 1.1、如何检索本文档 使用CSDN自带的“目录”功能进行检索&#xff0c;会更容易查找到自己需要的命令。 1.2、svn常用命令查询&#xff1a;help —— 帮助 在使用过程中&#xff0c;可随时使用help命令查看各常用svn命令&#xff1a; svn help2、检出及更新 2.1、…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...