用c++实现快速排序、最大子段和问题

6.2.2 快速排序

【问题】快速排序(quick sort)的分治策略如下(图6-5)。
(1)划分:(选定一个记录作为轴值,以轴值为基准将整个序列划分为两个子序列,轴值的位置在划分的过程中确定,并且左侧子序列的所有记录均小于或等于轴值,右侧子序列的所有记录均大于或等于轴值。
(2) 求解子问题:分别对划分后的每一个子序列进行递归处理。
(3) 合并:由于对子序列的排序是就地进行的,所以合并不需要执行任何操作。

【想法】首先对待排序记录序列进行划分,刻分的轴值应该遵循平衡子问题的原则,使划分后两个子序列的长度尽量相等。轴值的选择有很多方法,例如,可以随机选出一个记录作为轴值,从而期望划分是较平衡的。假设以第一个记录作为轴值,图6-6给出了、个划分的例子(黑体框代表轴值)。

        以轴值为基准将待排序序列划分为两个子序列后,对每一个子序列分别进行递归处理。图6-7所示是一个快速排序的完整的例子。

【算法实现】设函数Partition实现对序列r[first]~r[end]进行划分,函数QuickSort实现快速排序,程序如下。

#include <iostream>
using namespace std;


int Partition(int r[ ], int first, int end)
{
int temp, i = first, j = end;
while (i < j)
{
while (i < j && r[i] <= r[j]) j--; //右侧扫描
if (i < j)
{
temp = r[i]; r[i] = r[j]; r[j] = temp; //将较小记录交换到前面
i++;
}
while (i < j && r[i] <= r[j]) i++; //左侧扫描
if (i < j)
{
temp = r[i]; r[i] = r[j]; r[j] = temp; //将较大记录交换到后面
j--;
}
}
return i; //返回轴值记录的位置
}

void QuickSort(int r[ ], int first, int end) //快速排序
{
if (first < end)
{
int pivot = Partition(r, first, end); //划分,pivot是轴值的位置
QuickSort(r, first, pivot-1); //对左侧子序列进行快速排序
QuickSort(r, pivot+1, end); //对右侧子序列进行快速排序
}
}
int main( )
{
int i, n = 8, r[8] = {8,3,2,6,7,1,5,4};
    QuickSort(r, 0, n-1);

    for (i = 0; i < n; i++)
        std::cout << r[i] << " ";  // 打印排序后的元素

    std::cout << std::endl;

    return 0;
}

 

【算法分析】 最好情况下,每次划分对一个记录定位后,该记录的左侧子序列与右侧子序列的长度相同。在具有n个记录的序列中,一次划分需要对整个待划分序列扫描一遍,所需时间为O(n),则有:


        最坏情况下,待排序记录序列正序或逆序,每次划分只得到一个比上一次划分少一个记录的子序列(另一个子序列为空)。此时,必须经过n-1次递归调用才能把所有记录定位,而且第i趟划分需要经过n-i次比较才能找到第i个记录的位置,因此,时间复杂度为:

        平均情况下,设轴值记录的关键码第k小(1<=k<=n),则有:

        这是快速排序的平均时间性能,可以用归纳法证明,其数量级也为O(nlog以2为底n)。
        由于快速排序是递归执行的,需要一个工作栈来存放每一层递归调用的必要信息,栈
的最大容量与递归调用的深度一致。最好情况下要进行[log以2为底n]次递归调用,栈的深度为O(log,n);最坏情况下,要进行n-1次递归调用,栈的深度为O(n);平均情况下,栈的深度为O(log以2为底n).

6.3.1  最大子段和问题

应用实例
        国际期货市场某种商品在某个月的第1,2,...,31天的价格涨幅分别记为a1, a2,...,a31,若某天的价格下跌,这天的涨幅就是负值。如果想知道在连续哪些天,该商品的价格具有最高涨幅,究竟涨了多少,这个问题就可以抽象为最大子段和问题。

【算法实现】 最大子段和问题是按照位置进行划分的,设变量 center 表示序列的中间位置,数组a[n]存放整数序列,程序如下。

#include <iostream>
using namespace std;


int MaxSum(int a[ ], int left, int right)
{
int sum = 0, midSum = 0, leftSum = 0, rightSum = 0;
int i, center, s1, s2, lefts, rights;
if (left == right) //如果序列长度为1,直接求解
sum = a[left];
else
{
center = (left + right)/2; //划分
leftSum = MaxSum(a, left, center); //对应情况①,递归求解
rightSum = MaxSum(a, center+1, right); //对应情况②,递归求解
s1 = 0; lefts = 0; //以下对应情况③,先求解s1
for (i = center; i >= left; i--)
{
lefts += a[i];
if (lefts > s1) s1 = lefts;
}
s2 = 0; rights = 0; //再求解s2
for (i = center + 1; i <= right; i++)
{
rights += a[i];
if (rights > s2) s2 = rights;
}
midSum = s1 + s2; //计算情况③的最大子段和
if (midSum < leftSum) sum = leftSum; //合并解,取较大者
else sum = midSum;
if (sum < rightSum) sum = rightSum;
}
return sum;
}
int main( )
{
  int max, n = 6, r[6] = {-20, 11, -4, 13, -5, -2};
    max = MaxSum(r, 0, n - 1);
    cout << "最大子段和是:" << max << endl;
    return 0;

}
 

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

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

相关文章

全网最全的基于电机控制的38类simulink仿真全家桶----新手大礼包

整理了基于电机的38种simulink仿真全家桶&#xff0c;包含多种资料&#xff0c;类型齐全十分适合新手学习使用。包括但是不局限于以下&#xff1a; 1、基于多电平逆变器的无刷直流电机驱动simulink仿真 2、基于负载转矩的感应电机速度控制simulink仿真 3、基于滑膜观测器的永…

【全开源】JAVA情侣扭蛋机情侣游戏系统源码支持微信小程序+微信公众号+H5

让爱情更添趣味与惊喜 在繁忙的生活中&#xff0c;情侣们总是渴望找到一种新颖而有趣的方式来增进彼此的感情。为此&#xff0c;我们特别推出了“情侣扭蛋机情侣游戏系统”&#xff0c;让你们的爱情之旅更加充满趣味与惊喜。 情侣扭蛋机不仅是一个简单的游戏工具&#xff0c;…

计算机的内存是如何实现的

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…

成功解决Uncaught TypeError: Failed to resolve module specifier “vue“.

成功解决Uncaught TypeError: Failed to resolve module specifier “vue”. 一、问题背景 俗话说&#xff0c;温故而知新。首先&#xff0c;非常感谢我许哥&#xff0c;教会了我网页相关的知识&#xff0c;其他方面我也受益良多。言归正传&#xff0c;最近由于要运行Python&a…

【C语言习题】12.扫雷游戏

文章目录 1.扫雷游戏分析和设计1.1 扫雷游戏的功能说明1.2游戏界面&#xff1a;1.3游戏的分析和设计1.2.1 数据结构的分析1.2.2 ⽂件结构设计 2.扫雷游戏的代码实现3.代码讲解 1.扫雷游戏分析和设计 1.1 扫雷游戏的功能说明 使用控制台实现经典的扫雷游戏游戏可以通过菜单实现…

记笔记从学Typora开始--------------------(1)下载、安装、购买、激活

一、登录Typora官网 官网地址&#xff1a;Typora 二、鼠标往下滑&#xff0c;点击下载按钮 三、下载得到安装包&#xff0c;双击 四、一直点击下一步&#xff0c;进行安装 五、安装完成 六、启动Typoera 七、针对欢迎界面点击下一页 八、一直点击直到弹出以下软件激活界面 九…

深度盘点在当今经济形势下资深项目经理或PMO的或去或从

在当今经济形势下&#xff0c;资深项目经理&#xff08;Project Manager&#xff09;或项目管理办公室&#xff08;PMO&#xff09;的去向和选择受到多种因素的影响。以下是对他们可能面临的或去或从的深度盘点&#xff1a; 1、发展去向 1. 深化专业领域&#xff1a;在经济形势…

跨ROS系统通信:使用TCP实现节点间的直连

当涉及到在机器人操作系统&#xff08;ROS&#xff09;环境中的通信时&#xff0c;标准做法通常是在同一个ROS网络内通过话题和服务进行。但在某些特定情况下&#xff0c;比如当你有两个分布在不同网络中的ROS系统时&#xff0c;标准的通信方法可能不太适用。此时&#xff0c;一…

超实用的excel进销存管理系统(75份),自带库存预警,直接用!

进销存&#xff08;Inventory Management&#xff09;是企业管理中的一个核心组成部分&#xff0c;它涉及到商品的采购&#xff08;进货&#xff09;、销售和存储&#xff08;库存&#xff09;等环节。有效的进销存管理可以帮助企业降低成本、提高效率和客户满意度。 1. 采购管…

线程池的一些问题

核心线程数1.最大线程5.队列5.存活时间10s 1.场景一 如果核心线程数.被一直占用得不到释放.新进来1个任务.会怎么样?答: 会在队列中中死等. 只要进来的任务.不超过队列的长度,就会一直挡在队列中死等 package com.lin;import java.util.concurrent.Executors; import java.u…

knife4j案例

1.导入 <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId> </dependency>2.在配置类中加入 knife4j 相关配置并设置静态资源映射&#xff08;否则接口文档页面无法访问&#xff…

基于Python的jieba库分析《斗破苍穹》文本中的高频词汇

分析《斗破苍穹》文本中的高频词汇 在进行文本分析时&#xff0c;了解文本中出现频率较高的词汇对于把握文本的主题和风格非常有帮助。本文将介绍如何使用Python的jieba库对《斗破苍穹》这部小说的文本进行分词处理&#xff0c;并统计高频词汇的出现次数&#xff08;本文只统计…

【机器学习】:基于决策树与随机森林对数据分类

机器学习实验报告&#xff1a;决策树与随机森林数据分类 实验背景与目的 在机器学习领域&#xff0c;决策树和随机森林是两种常用的分类算法。决策树以其直观的树形结构和易于理解的特点被广泛应用于分类问题。随机森林则是一种集成学习算法&#xff0c;通过构建多个决策树并…

图解堆排序【一眼看穿逻辑思路】

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 目录 1、堆的概念2、实现堆排序前的准备工作3、堆排序的思路3.1 第一步3.2 第二步 4、结语 1、…

Cannot read properties of undefined (reading ‘init‘)报错

出现这个报错是印象项目没有引echarts包 npm i echarts 下包 然后在main.js中引入 import echarts from echarts Vue.prototype.$echarts echarts 如果还不行 import * as echarts from echarts; 更改一下引入方式 ok了

OpenHarmony 实战开发——使用分布式菜单创建点餐神器

随着社会的进步与发展&#xff0c;科技手段的推陈出新&#xff0c;餐饮行业也在寻求新的突破与变革&#xff0c;手机扫描二维码点餐系统已经成为餐饮行业的未来趋势&#xff0c;发展空间巨大&#xff1b;扫码点餐&#xff0c;是“互联网餐饮”潮流的产物&#xff0c;可以有效地…

Leetcode—2244. 完成所有任务需要的最少轮数【中等】

2024每日刷题&#xff08;136&#xff09; Leetcode—2244. 完成所有任务需要的最少轮数 实现代码 class Solution { public:int minimumRounds(vector<int>& tasks) {unordered_map<int, int> map;for(int task: tasks) {map[task];}int ans 0;// freq 1 …

嵌入式学习-输入捕获

简介 框图介绍 输入通道部分 比较捕获寄存器与事件生成 相关寄存器

【论文阅读 | 三维重建】3D Gaussian Splatting for Real-Time Radiance Field Rendering(3DGS)

Abstract 辐射场方法最近彻底改变了用多张照片或视频捕获的新颖视图合成&#xff0c;然而实现高视觉质量仍然需要训练和渲染成本高昂的神经网络&#xff0c;而最近更快的方法不可避免地要牺牲速度来换取质量。对于无边界和完整的场景和1080P分辨率的渲染&#xff0c;目前没有任…

低成本、功能强大!德思特提供一体化WiFi 6E信道测试方案!

​ 作者介绍 一、方案介绍 伴随WiFi 6E与WiFi 7的提出&#xff0c;WIFI划分出一个全新的5.925GHz-7.125GHz 之间的80MHz和160MHz频段。1200MHz的带宽是迄今为止最宽的&#xff0c;是之前2.4GHz和5GHz WiFi 频段可用带宽的数倍。此外WiFi 6E引入了以下技术&#xff1a; ● 多…