DS快速排序和归并排序的非递归实现(16)

文章目录

  • 前言
  • 一、快排的非递归实现
  • 二、归排的非递归实现
  • 总结


前言

  打破递归桎梏,迎接迭代解放!


一、快排的非递归实现

  我们要替代递归,就要用到迭代或者循环,也就是说,其核心思想是不变的,只是换一种方式来实现而已
  我们操控的是两个边界,利用栈来实现,这时候也就要考验你前面的知识是否学透了

void QuickSortNonR(int* arr, int n)
{
    // 初始化
    Stack st;
    StackInit(&st);

    // 先把最开始的两边界入栈
    StackPush(&st, n - 1);
    StackPush(&st, 0);

    // 进入循环,结束条件为空栈
    while (!isStackEmpty(&st)){
        int left = StackTop(&st);
        StackPop(&st);

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

        int key = Partition(arr, left, right);

        // 先排左边,因此先让右边界进栈
        if (key + 1 < right){
            StackPush(&st, right);
            StackPush(&st, key + 1);
        }

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

    StackDestroy(&st);
}

  栈的特性是先进后出,我们可以先将最外层的区间值入栈,即将 begin 与 end 入栈,之后进行选 key 划分的操作,判断左右区间是否合法,合法才能入栈,继续循环,如果所有区间都非法,栈就空了,循环也就结束了

二、归排的非递归实现

  归并排序属于后序排序因此不是通过使用栈去模拟非递归实现归并排序,因此在这里我们的基本思路是整个序列分为以gap为子序列,结束条件为gap < n(gap = n - 1 表示归并最后一次)
在这里插入图片描述
  这其实有点像归排里面的合并操作,只是由于是迭代版本,我们对于边界的处理要格外注意

下面是三种可能出现的边界问题

在这里插入图片描述
 对于一二两种,我们直接跳出循环,对于第三种,那说明还是有数据需要递归的,这时候我们修改下end2即可

void MergeSortNonR(int* arr, int n)
{
    int* tmp = (int*)malloc(sizeof(int) * n);
    int gap = 1;

    while (gap < n){
        for (int i = 0 ; i < n ; i += 2 * gap){
            // 拆成[i, i+gap-1],[i+gap, i+2*gap-1]两个区间
            int begin1 = i, end1 = i + gap - 1;
            int begin2 = i + gap, end2 = i + 2 * gap - 1;

            // 没有右区间,其实就是第一二种情况
            if (begin2 >= n){
                break;
            }

            // 右区间过长
            if (end2 >= n){
                end2 = n - 1;
            }

            // 归并
            int index = begin1; // index是tmp的下标
            while (begin1 <= end1 && begin2 <= end2){
                if (arr[begin1] < arr[begin2]){
                    tmp[index++] = arr[begin1++];
                }

                else {
                    tmp[index++] = arr[begin2++];
                }
            }

            while (begin1 <= end1){
                tmp[index++] = arr[begin1++];
            }

            while (begin2 <= end2){
                tmp[index++] = arr[begin2++];
            }

            // 拷贝
            for (int j = i ; j <= end2 ; j++){
                arr[j] = tmp[j];
            }

        }
        gap *= 2;
    }
    free(tmp);
}

总结

  我们的排序篇基本就结束拉!大家可以自己推导总结一下排序的稳定性!

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

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

相关文章

VMware:Windows主机与CentOS虚拟机文件互传文件共享

注意&#xff1a;本文使用Win10与VMware17pro互传 1. 本地创建文件夹 如下图创建一个文件夹&#xff0c;名字任意 2. 设置本地文件夹权限 右键文件夹 - - 属性 - - 共享 - - 高级共享 - - 权限 - - 如下图全部勾选 - - 应用 - - 确认 3. VMware中设置共享文件夹路径 第一步…

宿主机无法通过WinSCP连接虚拟机

排查步骤 1. 检查虚拟机是否启用了 SSH 服务 WinSCP 连接虚拟机需要 SSH 服务在虚拟机中运行。 检查 SSH 服务状态&#xff1a; 在虚拟机中执行以下命令&#xff1a;sudo systemctl status ssh 如果 SSH 服务未启动&#xff1a; sudo systemctl start ssh sudo systemct…

测试睡眠质量的app免费

测试睡眠质量的app免费&#xff0c;在快节奏的现代社会中&#xff0c;优质的睡眠对我们的身体健康和精神状态都至关重要。然而&#xff0c;许多人却面临睡眠质量不佳的问题。为了帮助大家更好地了解自己的睡眠状况&#xff0c;我们将介绍十款免费的睡眠质量测试APP&#xff0c;…

C#学习笔记(十一)

C#学习笔记&#xff08;十一&#xff09; 第八章 垃圾回收机制GC与类的静态方法一、垃圾回收机制GC1. 对象如何被销毁的 二、类的静态方法1. 静态方法的使用2. 为什么会报错2.1 静态方法定义中的报错2.2 方法使用中的报错 3. 什么情况下用静态 第八章 垃圾回收机制GC与类的静态…

CSS 居中那些事

一、父子元素高度确定 简单粗暴, 直接通过设置合适的 padding 或 margin 实现居中 <style>.p {padding: 20px 0;background: rgba(255, 0, 0, 0.1);}.c {width: 40px;height: 20px;background: blue;} </style> <div class"p"><div class"…

第 5 章:vuex

1. 理解 vuex vuex 是什么&#xff1a; 概念&#xff1a;专门在 Vue 中实现集中式状态&#xff08;数据&#xff09;管理的一个 Vue 插件&#xff0c;对 vue 应用中多个组件的共享状态进行集中式的管理&#xff08;读/写&#xff09;&#xff0c;也是一种组件间通信的方式&am…

多IP访问浏览器

添加多个ip地址 nmcli connection modify ens160 ipv4.method manual ipv4.addresses 192.168.61.100/24 ipv4.addresses 192.168.61.200/24 ipv4.addresses 192.168.61.128 ipv4.gateway 192.168.61.2 ipv4.dns 114.114.114.114

linux多窗口调试一些常用命令

在 vim 或 neovim 中使用分屏移动光标的方式&#xff1a; 希望光标从左窗口移动到右侧窗口&#xff1a; 按 Ctrlw 然后按 l&#xff08;小写的 L&#xff09;&#xff0c;光标就会从左边窗口移动到右边窗口。 其它分屏操作&#xff1a; Ctrlw h&#xff1a;移动到左边的窗…

民宿在线预订:SpringBoot技术实践指南

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

【VUE小型网站开发】初始环境搭建

1. 初始化VUE项目 1.1 创建vue项目 1.2 删除多余的界面 根据自己情况删除红框内的文件 清理app页面代码 1.3 引入vue-router 1.3.1 下载vue-router npm install vue-router1.3.2 配置vue-router 在 main.js 或 main.ts 中引入 vue-router import ./assets/main.css im…

MySQL-28.事务-介绍与操作

一.为什么需要事务 -- 事务 -- 删除部门 delete from tb_dept where id 1;-- 删除部门下的员工 delete from tb_emp where dept_id 1; 这样的话就可以成功删除&#xff0c;但是有一个问题&#xff1a;如果部门id1的被成功删除了&#xff0c;但是部门下的员工在删除时出错了…

各种查询sql介绍

1. 关联查询&#xff08;JOIN&#xff09; 关联查询用于从多个表中检索数据。它基于两个或多个表之间的共同字段&#xff08;通常是主键和外键&#xff09;来组合数据。 内连接&#xff08;INNER JOIN&#xff09;&#xff1a; sql SELECT a.name, b.order_date FROM custome…

git add操作,文件数量太多卡咋办呢,

git add介绍 Git的add命令是用于将文件或目录添加到暂存区&#xff08;也就是索引库&#xff09;&#xff0c;以便在后续的提交&#xff08;commit&#xff09;操作中一并上传到版本库的。具体来说&#xff0c;git add命令有以下几种常见用法&#xff1a; 添加单个文件&#…

【每日一题】24.10.14 - 24.10.20

10.14 直角三角形1. 题目2. 解题思路3. 代码实现&#xff08;AC_Code&#xff09; 10.15 回文判定1. 题目2. 解题思路3. 代码实现&#xff08;AC_Code&#xff09; 10.16 二次方程1. 题目2. 解题思路3. 代码实现&#xff08;AC_Code&#xff09; 10.17 互质1. 题目2. 解题思路3…

基于单片机的多功能鱼缸控制系统设计

本设计以STC12C5A60S2单片机为核心的多功能鱼缸控制系统&#xff0c;该系统可分别利用温度传感器、水位传感器和浑浊度传感器来检测鱼缸内部的水温、液体高度和浑浊程度&#xff0c;并在显示屏上进行显示。若检测结果超出阈值范围&#xff0c;则继电器工作从而控制内部环境。通…

Golang | Leetcode Golang题解之第482题秘钥格式化

题目&#xff1a; 题解&#xff1a; func licenseKeyFormatting(s string, k int) string {ans : []byte{}for i, cnt : len(s)-1, 0; i > 0; i-- {if s[i] ! - {ans append(ans, byte(unicode.ToUpper(rune(s[i]))))cntif cnt%k 0 {ans append(ans, -)}}}if len(ans) &…

汽车电子存储解决方案:IS61WV20488FALL

ISSI在SRAM领域的技术创新体现在采用高性能CMOS工艺制造&#xff0c;提供低功耗设计&#xff0c;以及支持宽温度范围的稳定运行。其产品集成了错误更正代码&#xff08;ECC&#xff09;&#xff0c;增强了数据完整性和可靠性。ISSI的SRAM优化了数据处理速度&#xff0c;提供多访…

教你不用下载 maven,不用配置环境变量,在 idea 上创建 maven 项目

我的主页&#xff1a;2的n次方_ 1. Maven Maven是⼀个项⽬管理⼯具, 通过 pom.xml ⽂件的配置获取 jar 包&#xff0c;⽽不⽤⼿动去添加 jar 包&#xff0c;这样就大大的提高了开发效率 2. Maven 的核心功能 2.1. 项目构建 创建第一个 Maven 项目 Maven 提供了标准的…

CDC变更数据捕捉技术是什么?和ETL有什么不同?

一、什么是CDC技术? 变更数据捕获&#xff08;Change Data Capture&#xff0c;简称 CDC&#xff09;是一种用于识别和跟踪数据源中发生变化的数据的技术。 工作原理&#xff1a; 1.监测数据源&#xff1a;CDC 工具会持续监测指定的数据源&#xff0c;如数据库表、文件系统…

Qt开发------容器控件(QWidget,QFrame、QMainWindow、QScrollArea)

目录 一、QWidget 二、QFrame 三、QMainWindow 四、QScrollArea&#xff08;面板滚动&#xff09; 层次结构如下&#xff1a; QObject└── QPaintDevice└── QWidget├── QMainWindow├── QDialog├── QFrame│ ├── QLabel│ ├── QSplitter│ …