【C语言】【数据结构初阶】 快排变慢排?怎么个事儿?

news2024/11/23 12:49:05

一.为何“快排”变“慢排”

我们知道,快排是一种很好的排序算法。但是在极少数的一些情况下,“快速排序”好像名不副实了。比如:1,2,1,2,1,2,1。。。。。。这样的数列

并且:递归深度太深,有栈溢出的风险。

这样,我们就得到了一个很可惜的结论:快排不是万金油。

但是,这是指的递归版本的快排,我们可以写非递归方式的快速排序,来看看是否能解决这个问题。

二.更改思路

想要改成非递归的版本,那么循环是否可以呢?

这里涉及到了左右区间分别递归,想要用循环实现,还是不大容易的。

//快速排序
void QuickSort(int* a, int left,int right)
{
	if (left >= right)
	{
		return;
	}
	int keyi = Partion(a, left, right);
	QuickSort(a, left, keyi - 1);
	QuickSort(a, keyi + 1, right);
}

那么,我们还有其它方式来解决这个问题吗?

答案是当然有。

我们可以用栈模拟

栈中存储的是需要排序的区间。栈是后入先出的。

如果是C++,那我们可以直接用STL里的,但是由于我们这里选择使用C语言来实现,所以我们需要先写一个栈。

下面是我们简单实现的一个栈。

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

typedef int STDataType;

typedef struct Stack
{
	STDataType* a;
	int top;  //栈中数据数量
	int capacity; //栈的容量
}ST;

//检查空间是否足够,不够则扩容
void CheckCapacity(ST* ps)
{
	if (ps->top == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = realloc(ps->a, sizeof(STDataType) * newcapacity);
		if (tmp == NULL)
		{
			printf("realloc failed!\n");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}
}

//初始化
void StackInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}

//销毁
void StackDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}

//插入数据
void StackPush(ST* ps, STDataType x)
{
	assert(ps);

	CheckCapacity(ps);

	ps->a[ps->top] = x;
	ps->top++;
}

//删除数据
void StackPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	ps->top--;
}

//取出栈顶数据
STDataType StackTop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	return ps->a[ps->top - 1];
}

//计算栈中数据数量
int StackSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

//判断栈是否为空
bool StackEmpty(ST* ps)
{
	assert(ps);

	return ps->top == 0;
}

三.具体实现

我们可以使用栈来模拟递归过程:

每次从栈中取出一段区间,单趟分割处理左右子区间入栈。

#include"sort.h"
#include"Stack.h"

void Swap(int* p, int* q)
{
	int tmp = *p;
	*p = *q;
	*q = tmp;
}

int PartSort1(int* a, int left, int right)
{
	int keyi = left;

	while (left < right)
	{
		while (a[right] >= a[keyi] && left < right)
		{
			right--;
		}
		while (a[left] <= a[keyi] && left < right)
		{
			left++;
		}

		Swap(&a[left], &a[right]);
	}

	Swap(&a[left], &a[keyi]);
	return left;
}

void QuickSort1(int* a, int left, int right)
{
	if (left >= right)
	{
		return;
	}

	int keyi = PartSort1(a, left, right);

	QuickSort(a, left, keyi - 1);
	QuickSort(a, keyi + 1, right);
}




void QSortNonR(int* a, int begin, int end)
{
	ST st;
	StackInit(&st);

	StackPush(&st, end);
	StackPush(&st, begin);

	while (!StackEmpty(&st))
	{
		int left = StackTop(&st);
		StackPop(&st);

		int right = StackTop(&st);
		StackPop(&st);

		int keyi = PartSort1(a, left, right);

		if (keyi + 1 < right)
		{
			StackPush(&st, right);
			StackPush(&st, keyi + 1);
		}

		if (left < keyi - 1)
		{
			StackPush(&st, keyi - 1);
			StackPush(&st, left);
		}
	}

	StackDestroy(&st);

}

四.测试运行

 

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

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

相关文章

十七、web网页像素知识

目录&#xff1a; 像素视口 一、像素 像素&#xff1a;- 屏幕是由一个个发光的小点构成&#xff0c;这一个个的小点就是像素- 分辨率&#xff1a;1920 x 1080 说的就是屏幕中小点的数量- 在前端开发中像素要分成两种情况讨论&#xff1a;css像素和物理像素- 物理像素&#xff…

具有电动驱动的四足机器人模型研究(SimulinkMatlab代码)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Mac的docker安装redis

Mac的docker安装redis 1、docker search redis NAME DESCRIPTION STARS OFFICIAL AUTOMATED redis Redis is an open source key-value store that… 12205 …

unity 2018.4.0+SteamVR1.2.2+VRTK3.2.1报错解决

开发案例参考 07-游乐设备选择场景搭建_哔哩哔哩_bilibili 导入之后代码报错Assets/SteamVR/Editor/SteamVR_Settings.cs(135,49): error CS0117: UnityEditorInternal.VR.VREditor does not contain a definition for GetVREnabledDevices 解决方法 打开SteamVR_Settings 脚…

深入了解C语言中scanf()函数的用法

目录 正文 一、基本用法 二、格式化字符串 三、多个输入值 四、错误处理 五、总结 正文 在C语言中&#xff0c;scanf()函数是一个非常有用的输入函数&#xff0c;它允许我们从用户那里获取输入&#xff0c;并将输入存储到指定的变量中。本文将详细介绍scanf()函数的使用方…

【ELK企业级日志分析系统】部署Filebeat+Kafka+Logstash+Elasticsearch+Kibana集群详解(EFLFK)

部署FilebeatKafkaLogstashElasticsearchKibana集群详解 1. Kafka1.1 Kafka概述1.1.1 为什么需要消息队列&#xff08;MQ&#xff09;1.1.2 使用消息队列的好处 1.2 消息队列的两种模式1.3 Kafka定义1.3.1 Kafka简介1.3.2 Kafka的特性1.3.3 Kafka系统架构1.3.4 Partation数据路…

微信消息延迟怎么办?

微信是我们常用的聊天工具&#xff0c;那在微信聊天中&#xff0c;相信有很多朋友都遇到过&#xff0c;明明对方的消息已经发过来了&#xff0c;可微信就是没有显示。这就很容易发生误会或者耽误很多事情。 那么微信消息延迟是什么原因导致的呢&#xff1f; 网络信号差 当我们的…

PostgerSQL证书长什么样子

PostgerSQL证书长什么样子 一、证书样式&#xff1a; 重点请看公章&#xff1a;工业和信息化部教育与考试中心 仿冒、假借、诋毁公章&#xff0c;可向工信部和当地公安机关举报 二、发证单位 证书由工业和信息化部教育与考试中心进行制作。 PostgerSQL证书发证单位&…

数据可视化:揭开数据的视觉奇迹

随着大数据时代的到来&#xff0c;我们面临着海量的数据&#xff0c;如何从中获取有价值的信息成为一项重要的挑战。数据可视化作为一种强大的工具&#xff0c;通过图表、图形和交互界面&#xff0c;将数据转化为可视化的形式&#xff0c;帮助我们更好地理解和分析数据。 数据可…

特斯拉降价阴影下,智己如何「登高」?

作者 | 刘然 来源 | 洞见新研社 都说背靠大树好乘凉&#xff0c;但背靠上汽集团的智己汽车&#xff0c;反而水深火热。 2021年&#xff0c;在智己正式向外界公布了“豪华纯电智能轿车”智己L7之后&#xff0c;其CEO刘涛曾放出豪言&#xff1a;“我们在未来的很多年后再回顾今…

工作--输入文档

知识点&#xff1a; 1、find 返回的是对象&#xff0c;找到第一个满足条件的 就停止遍历&#xff0c;返回此对象 &#xff01;2、async...await 使用场景&#xff1a; 1、一般循环中 不给方法加async...await 2、then里面 的一块是整体 3、watch监听&#xff1a; 数组&…

提高视觉检测系统稳定性的隐藏办法——10G高速图像采集卡

提高视觉检测系统稳定性的隐藏办法——10G高速图像采集卡 目前&#xff0c;随着我国各方面配套基础设施建设的完善&#xff0c;企业技术、资金的积累&#xff0c;各行各业积极探索和大胆的尝试机器视觉技术&#xff0c;实现工业自动化、智能化。在机器视觉系统的使用过程中&am…

SQL 删除重复的电子邮箱

196 删除重复的电子邮箱 SQL架构 表: Person -------------------- | Column Name | Type | -------------------- | id | int | | email | varchar | -------------------- id是该表的主键列。 该表的每一行包含一封电子邮件。电子邮件将不包含大写字母。 删除 所有重复的电…

APK的数字签名检测

检测命令&#xff1a; C:\Program Files\Java\jdk1.8.0_111\bin\jarsigner.exe -verify APK 文 件 路 径 -verbose –certs 当输出结果为“jar 已验证”时&#xff0c;表示签名正常 检测签名的 CN 及其他字段是否正确标识客户端程序的来源和发布者身份 如上图&#xff0c;说明…

第三章:DeepLabV3——重新思考用于语义图像分割的扩张卷积

0.摘要 在这项工作中&#xff0c;我们重新思考了扩张卷积&#xff08;atrous convolution&#xff09;&#xff0c;这是一种能够明确调整卷积滤波器的感受野&#xff08;field-of-view&#xff09;以及控制由深度卷积神经网络计算的特征响应的分辨率的强大工具&#xff0c;应用…

Linux基础(二)用户权限及修改sudo、getent、chmod、chown、yum、systemctl、ln、日期和时间、IP地址管理、网络请求与下载

上接&#xff1a; Linux基础&#xff08;一&#xff09;Linux基础命令、vi/vim编辑器_独憩的博客-CSDN博客 目录 用户权限 sudo命令 用户和用户组 用户组管理&#xff1a; 用户管理&#xff1a; getent 权限认知 chmod命令修改权限 chown修改文件文件夹的所属用户和用…

119、仿真-51单片机温湿度光照强度LCD 1602显示报警设计(Proteus仿真+程序+元器件清单等)

方案选择 单片机的选择 方案一&#xff1a;AT89C52是美国ATMEL公司生产的低电压&#xff0c;高性能CMOS型8位单片机&#xff0c;器件采用ATMEL公司的高密度、非易失性存储技术生产&#xff0c;兼容标准MCS-51指令系统&#xff0c;片内置通用8位中央处理器(CPU)和Flash存储单元…

【计算机视觉 | 目标检测】arxiv 计算机视觉关于目标检测的学术速递(7 月 13 日论文合集)

文章目录 一、检测相关(8篇)1.1 Exposing the Fake: Effective Diffusion-Generated Images Detection1.2 Large Class Separation is not what you need for Relational Reasoning-based OOD Detection1.3 Visualization for Multivariate Gaussian Anomaly Detection in Imag…

unity计时,1秒执行一次

1.核心代码示例 2.代码 using System.Collections; using System.Collections.Generic; using UnityEngine;public class AddRandomChilden : MonoBehaviour {// Debug.Log("开始进入update");float i 0;// Start is called before the first frame updatevoid Sta…

【智慧交通项目实战】 《 OCR车牌检测与识别》(五):模型部署与优化

&#x1f468;‍&#x1f4bb;作者简介&#xff1a; CSDN、阿里云人工智能领域博客专家&#xff0c;新星计划计算机视觉导师&#xff0c;百度飞桨PPDE&#xff0c;专注大数据与AI知识分享。✨公众号&#xff1a;GoAI的学习小屋 &#xff0c;免费分享书籍、简历、导图等&#xf…