2,认识N(logN)的排序【p3】

认识N( logN} 的排序

  • 2.1归并排序
    • 2.1.1代码实现归并排序
      • 2.1.1.1自己c++实现归并排序
      • 2.1.1.2gptc++实现归并排序
      • 2.1.1.3总结
      • 2.1.1.4比较行为
    • 2.1.2归并排序使用master公式
    • 2.1.3归并排序的扩展
      • 2.1.3.1小和问题
      • 2.1.3.2逆序对问题
  • 2.2快排、荷兰国旗问题
    • 2.2.1问题一
    • 2.2.2问题二(荷兰国旗问题)
      • 2.2.2.1快排问题1.0
      • 2.2.2.2快排问题2.0
      • 2.2.2.3快排问题3.0

2.1归并排序

时间复杂度O(N*logN),额外空间复杂度O(N)

整体就是一个简单递归,左边排好序,右边排好序,让其整体有序
让其整体有序的过程里用了排外序方法
利用master公式来求解时间复杂度
归并排序的实质

二分,左边排好序,右边排好序,左1和右1比较,小的写入新内存,(如右1小,写入右1),左1和右2比较,(如右2小,写入右2),左1和右3比较,(如左1小,写入左1),此时新内存中为(右1,右2,左1),左2和右3比较……
在这里插入图片描述

2.1.1代码实现归并排序

2.1.1.1自己c++实现归并排序

自己实现c++代码

#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
void print01(int val)
{
	std::cout << val << " ";
}
void test01()
{
	std::vector<int> Arr = { 5,6,9,4,2,3,7,5,6,8 };
	int length = Arr.size();
	std::multiset<int>Up;
	std::multiset<int>Down;
	if (length % 2 == 1)
	{
		for (int i = 0; i < (length + 1) / 2; i++)
		{
			std::vector<int>::iterator it = Arr.end()-1;
			Up.insert(*it);
			Arr.pop_back();
		}
		for (int j = 0; j < (length - 1) / 2; j++)
		{
			std::vector<int>::iterator it = Arr.end()-1;
			Down.insert(*it);
			Arr.pop_back();
		}
	}
	else
	{
		for (int i = 0; i < length / 2; i++)
		{
			std::vector<int>::iterator it = Arr.end()-1;
			Up.insert(*it);
			Arr.pop_back();
		}
		for (int i = 0; i < length / 2; i++)
		{
			std::vector<int>::iterator it = Arr.end()-1;
			Down.insert(*it);
			Arr.pop_back();
		}
	}
	
	std::vector<int>End;
	for (int q = 0; q < length; q++)
	{
		std::multiset<int>::iterator it1 = Up.begin();
		std::multiset<int>::iterator it2 = Down.begin();
		if (Up.size() != 0 && Down.size() != 0)
		{
			if (*it1 < *it2)
			{
				End.push_back(*it1);
				Up.erase(it1);
			}
			else
			{
				End.push_back(*it2);
				Down.erase(it2);
			}
		}
		else if(Up.size() != 0 || Down.size() != 0)
		{
			if (Up.size() != 0)
			{
				End.push_back(*it1);
				Up.erase(it1);
			}
			else
			{
				End.push_back(*it2);
				Down.erase(it2);
			}
		}
		else
		{
			break;
		}
	}

	for_each(End.begin(), End.end(),print01);
}
int main()
{
	test01();
	system("pause");
	return 0;
}

2.1.1.2gptc++实现归并排序

chatgpt实现

#include<iostream>
#include<set>
#include<algorithm>
#include<vector>

void print01(int val)
{
    std::cout << val << " ";
}

void test01()
{
    std::vector<int> Arr = { 5,6,9,4,2,3,7,5,6,8 };
    std::multiset<int> Up, Down;
    
    int length = Arr.size();
    int halfLength = (length + 1) / 2;
    
    for (int i = 0; i < halfLength; i++)
    {
        Up.insert(Arr.back());
        Arr.pop_back();
    }
    
    for (int i = 0; i < halfLength; i++)
    {
        Down.insert(Arr.back());
        Arr.pop_back();
    }

    std::vector<int> End;
    while (!Up.empty() && !Down.empty())
    {
        if (*Up.begin() < *Down.begin())
        {
            End.push_back(*Up.begin());
            Up.erase(Up.begin());
        }
        else
        {
            End.push_back(*Down.begin());
            Down.erase(Down.begin());
        }
    }

    // 处理剩下的元素
    for (const auto& val : Up)
    {
        End.push_back(val);
    }

    for (const auto& val : Down)
    {
        End.push_back(val);
    }

    std::for_each(End.begin(), End.end(), print01);
}

int main()
{
    test01();
    std::system("pause");
    return 0;
}

2.1.1.3总结

总结自己实现和gpt实现,给予gpt的要求是使用归并排序,减少代码行数
gpt没有使用迭代器来接收 Arr 中的值,将迭代器 it 初始化为 Arr 的最后一个元素的迭代器。而是直接使用Arr的迭代器begin

2.1.1.4比较行为

选择排序、冒泡排序、插入排序浪费了大量的比较行为
而归并排序虽然也进行了大量的比较,但是归并行为有效地利用对比,因为每一次比较行为都变成了有序的东西(有结果)

2.1.2归并排序使用master公式

master公式
T(N)=a* T(N/b)+O(N^d)
log(b,a)>d -> 复杂度为 O(N^log(b,a))
log(b,a)=d -> 复杂度为 O(N^d *logN)
log(b,a)< d -> 复杂度为 O(N^d)

logba<d 的时间复杂度O(Nd)
logba>d 的时间复杂度O(N^logb a )
logba==d 的时间复杂度O(Nd *logN)

上面例子中
T(N)=2T(N/2)+O(N),符合master公式
a=2,b=2,d=1
log22==1,所以时间复杂度为O(N)

2.1.3归并排序的扩展

小和问题和逆序对问题

2.1.3.1小和问题

在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和,求一个数组的小和
例:[1,3,4,2,5]1左边比1小的数,没有;3左边比3小的数,1;4左边比4小的数,1、3;2左边比2小的数,1;5左边比5小的数,1、3、4、2;所以小和为1+1+3+1+1+3+4+2=16

正常情况下时间复杂度为O(N2)

找寻更快的方法:
[1,3,4,2,5]1右边有4个数比1大14=4,3右边两个数比3大32=6,4右边1个数比4大14=4,2右边1个数比2大21=2;4+6+4+2=16
请添加图片描述
1,3对比产生1个1。返回排序13(排序,从小到大)
1,4对比产生1个1,3。4对比产生1个3,1,3,4.返回排序134
请添加图片描述
2,5对比产生1个2,返回排序25
请添加图片描述
134中指向1,25中指向2,对比产生2个1,拷贝1
134中指向3,25中指向2,对比3大,拷贝2,25中指向5,对比产生1个3,拷贝3
134中指向4,25中指向2,对比4大,25中指向5,对比产生1个4,拷贝4,拷贝5
12345
小和1+1+3+2+2+3+4=16

1和2对比产生的2个1不是通过遍历找到的2,而是直接通过下标begin() 和end()找到

请添加图片描述
如图情况左右相对,一定要先拷贝右组的数,而不是左组

2.1.3.2逆序对问题

在一个数组中,左边的数如果比右边的数大,则折两个数构成一个逆序对,请打印所有逆序对

例:3,2,4,5,0
32,30,20,40,50

2.2快排、荷兰国旗问题

2.2.1问题一

给定一个数组arr,和一个数num,请把小于等于num的数放在数组的左边,大于num的数放在数组的右边。要求额外空间复杂度0(1),时间复杂度0(N)

35674358 num=5
准备一个变量i
情况a,[i]<=num,[i]和<=区的下一个数交换,<=区右扩,i++
情况b,[i]>num,i++
3和num5比较,num5大,情况a执行
5和num5比较,等于num5,情况a执行
6和num5比较,6大,情况b执行
……

2.2.2问题二(荷兰国旗问题)

给定一个数组arr,和一个数num,请把小于num的数放在数组的左边,等于num的数放在数组的中间,大于num的数放在数组的右边。要求额外空间复杂度0(1),时间复杂度O(N)

35674358 num=5
准备一个变量i
情况a,[i]<num,[i]和<区的下一个数交换,<区右扩,i++
情况b,[i]>num,[i]和>区的上一个数交换,>区左扩,i不动
情况c,[i]==num,i++
请添加图片描述
请添加图片描述

2.2.2.1快排问题1.0

时间复杂度O(N2)

在一串数里,拿最后一个数作为num,<=num放左边,>=num放右边,num和>=num区域的第一个数做交换。再次重复,取新的最后一个数num

2.2.2.2快排问题2.0

时间复杂度O(N2)
最好的情况为T(N)=2T(N/2)+O(N) , 时间复杂度为O(N*logN)
最坏的情况没有左侧部分或右侧部分,时间复杂度O(N2)

在一串数里,拿最后一个数作为num,<num放左边,>num放右边,==num放中间,最后一个数和>5区域第一个数交换。在<num,>num区域做递归

分析:
快排2.0比快排1.0稍快,因为快排2.0一次搞定一批数
划分值越靠近两侧,复杂度越高;划分之越靠近中间,复杂度越低
可以轻而易举的举出最差的例子,所以不改进的快速排序时间复杂度为O(N^2)
请添加图片描述
4356501785,取尾数5为num值,排序出三个区域
<5 ,=5 ,>5 5
尾数5和>5区域的第一个数互换
<5 (4301),=5(555) ,>5(786)
4301取尾数1,排序出三个区域
<1 (0),=1 (),>1(43),1
0 1 43
43取尾数3,排出三个区域……
786取尾数6,排序出三个区域
<6 () ,=6 () ,>6(78), 6
6 78
78取尾数8,排出三个区域……

2.2.2.3快排问题3.0

请添加图片描述
L到R位置上,随机取一个数,和最后一个数交换,然后用此数做划分
原理:
有可能
T(N)=T(N/5)+T(4/5*N)+O(N)
T(N)=T(N/3)+T(2N/3)+O(N)
T(N)=2T(N/2)+O(N)
T(N)=T(4N/5)+T(N/5)+O(N)
…………
所有情况都是等概率1/n的,所以汇总所有可能,把所有式子求概率累加,再求数学长期期望,得出结果O(N * logN)

空间复杂度:O(logN)

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

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

相关文章

数电基础知识学习笔记

文章目录&#xff1a; 一&#xff1a;逻辑门 1.逻辑门电路的分类 1.1 按逻辑&#xff08;逻辑门&#xff09; 1.1.1 逻辑定义 1.1.2 常见数字电路相关符号 1.1.3 电路图表示 1.1.4 逻辑门电路图像符号 1.2 按电路结构 1.3 按功能特点 2.高低电平的含义 3.常见的门…

C#实现数据库数据变化监测(sqlservermysql)

监测数据库表数据变化&#xff0c;可实现数据库同步&#xff08;一主一从&#xff08;双机备份&#xff09;&#xff0c;一主多从&#xff08;总部数据库&#xff0c;工厂1&#xff0c;工厂2&#xff0c;工厂数据合并到总部数据&#xff09;&#xff09; sqlserver 启用数据库…

uni-app在小米手机上运行【步骤细节】

注意细节重点&#xff1a; 1.手机使用数据线与电脑连接&#xff0c;手机连接模式必须是传输文件模式 2.手机必须打开开发者模式 3.打开开发者模式后&#xff0c;仔细浏览并调整USB调试权限&#xff0c;重点打开USB是否允许安装按钮&#xff01;&#xff01;&#xff01; 操作步…

黄东旭:The Future of Database,掀开 TiDB Serverless 的引擎盖

在 PingCAP 用户峰会 2023 上&#xff0c; PingCAP 联合创始人兼 CTO 黄东旭 分享了“The Future of Database”为主题的演讲&#xff0c; 介绍了 TiDB Serverless 作为未来一代数据库的核心设计理念。黄东旭 通过分享个人经历和示例&#xff0c;强调了数据库的服务化而非服务化…

020 - STM32学习笔记 - Fatfs文件系统(二) - 移植与测试

020 - STM32学习笔记 - Fatfs文件系统&#xff08;二&#xff09; - 移植与测试 上节学习了FatFs文件系统的相关知识&#xff0c;这节内容继续学习在STM32上如何移植FatFs文件系统&#xff0c;并且实现文件的创建、读、写与删除等功能。各位看官觉得还行的话点点赞&#xff0c…

Spring Tool Suite 4

参考&#xff1a;Spring tool suite4 安装及配置_springtoolsuite4_猿界零零七的博客-CSDN博客 下载&#xff1a;Spring | Tools 将下载的JAR进行解压两次&#xff0c;直至解压出contents中的sts 双击启动 第一次打开需要指定工作区文件夹 配置Maven的config 安装插件

(笔记)Layout知识点汇总(积累量变)

Layout知识点汇总 布线1、电容电阻中间不要穿线2、线宽不要超过焊盘&#xff0c;引出后加粗 拐角1、layout&#xff1a;钝角走线 线宽间距1、注意和差分信号线的距离 焊盘1、焊盘中心出线2、线连接到焊盘中心 布局1、时钟线包地处理2、音频的左右声道&#xff0c;加粗&#xff…

【多模态】18、ViLD | 通过对视觉和语言知识蒸馏来实现开集目标检测(ICLR2022)

文章目录 一、背景二、方法2.1 对新类别的定位 Localization2.2 使用 cropped regions 进行开放词汇检测2.3 ViLD 三、效果 论文&#xff1a;Open-vocabulary Object Detection via Vision and Language Knowledge Distillation 代码&#xff1a;https://github.com/tensorflo…

C语言每日一题之整数求二进制1的个数

今天分享一道题目&#xff0c;用三种方法来求解 二进制1的个数 方法1 我们的十进制除10和取余数就可以得到我们每一位的数字&#xff0c;那我们的二进制也可 以 #include<stdio.h> int num_find_1(unsigned int n) {int count 0;while (n){if (1 n % 2){count;}n / 2…

element中tabs组件,click事件点击拿到当前item的所有数据

话不多说&#xff0c;直接上代码&#xff1a; 添加一个:value&#xff0c;然后在用JSON.stringify(item)转一下就可以了&#xff0c;这样就会存在$attrs.value这个里面了。 接着在点击事件里面获取使用el.$attrs.value&#xff0c;注意这里在拿到这个值时&#xff0c;再用JSON…

事务的隔离级别以及传播机制的详细讲解

1.为什么需要事务&#xff1f; 事务就是将一组操作封装成一个执行单元&#xff0c;要么全部执行成功&#xff0c;要么全部执行失败 ⽐如转账分为两个操作&#xff1a; 第⼀步操作&#xff1a;A 账户 -100 元第⼆步操作&#xff1a;B 账户 100 元 如果没有事务&#xff0c;第⼀…

SQL-每日一题【1173. 即时食物配送 I】

题目 配送表: Delivery 如果顾客期望的配送日期和下单日期相同&#xff0c;则该订单称为 「即时订单」&#xff0c;否则称为「计划订单」。 查询即时订单所占的百分比&#xff0c; 保留两位小数。 查询结果如下所示。 示例 1: 解题思路 1.题目要求我们查询出顾客期望的配送日…

回归预测 | MATLAB实现SO-CNN-LSTM蛇群算法优化卷积长短期记忆神经网络多输入单输出回归预测

回归预测 | MATLAB实现SO-CNN-LSTM蛇群算法优化卷积长短期记忆神经网络多输入单输出回归预测 目录 回归预测 | MATLAB实现SO-CNN-LSTM蛇群算法优化卷积长短期记忆神经网络多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 MATLAB实现SO-CNN-LS…

Ubuntu20.04安装Autoware.universe并与Awsim联调

文章目录 引言一、安装依赖1.1 安装git1.2 克隆Autoware到本地1.3 自动安装相关依赖1.4 安装显卡驱动1.5 安装ROS2 Galactic1.6 安装ros2_dev_tools1.7 安装rmw_implementation1.8 安装pacmod1.9 安装autoware_core1.10 安装autoware universe dependencies1.11 安装pre_commit…

论文阅读-BotPercent: Estimating Twitter Bot Populations from Groups to Crowds

目录 摘要 引言 方法 数据集 BotPercent架构 实验结果 活跃用户中的Bot数量 Bot Population among Comment Sections Bot Participation in Content Moderation Votes Bot Population in Different Countries’ Politics 论文链接&#xff1a;https://arxiv.org/pdf/23…

解密低价正规渠道的来源:影视会员肯德基点餐直充api接口

话费充值 接口已经整合移动、联通、电信三网话费充值渠道。话费可以说是全民所需&#xff0c;对于平台引流&#xff0c;增强平台日活跃度可以提供不小的帮助。 肯德基在线点餐 接口整合了各大城市的肯德基门店&#xff0c;支持门店选择&#xff0c;在线点餐 提前点餐领取&a…

Xilinx AXI VIP使用教程

AXI接口虽然经常使用&#xff0c;很多同学可能并不清楚Vivado里面也集成了AXI的Verification IP&#xff0c;可以当做AXI的master、pass through和slave&#xff0c;本次内容我们看下AXI VIP当作master时如何使用。 新建Vivado工程&#xff0c;并新建block design&#xff0c;命…

设计模式-备忘录模式在Java中使用示例-象棋悔棋

场景 备忘录模式 备忘录模式提供了一种状态恢复的实现机制&#xff0c;使得用户可以方便地回到一个特定的历史步骤&#xff0c;当新的状态无效 或者存在问题时&#xff0c;可以使用暂时存储起来的备忘录将状态复原&#xff0c;当前很多软件都提供了撤销(Undo)操作&#xff0…

虚拟现实技术(VR)

目录 1.什么是虚拟现实技术 2.虚拟现实技术的由来 3.虚拟现实技术给人类带来的好处 4.虚拟现实技术未来的走向 1.什么是虚拟现实技术 虚拟现实技术&#xff08;Virtual Reality&#xff0c;简称VR&#xff09;是一种通过计算机生成的模拟环境&#xff0c;使用户能够身临其境…

原生html—摆脱ps、excel 在线绘制财务表格加水印(html绘制表格js加水印)

文章目录 ⭐前言⭐html标签&#x1f496;table表格的属性&#x1f496;实现财务报表 ⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享原生html——绘制表格报表加水印。 背景&#xff1a;解决没有ps的情况下使用前端html制作表格报表。 html介绍 HTML&#xf…