算法设计与分析(线性时间选择算法

目录

  • 线性时间选择算法(QuickSelect)实现
  • 注意事项
  • 有可能出现的特殊情况:
  • 小结:

线性时间选择算法(QuickSelect)实现

线性时间选择算法 是快速排序算法的一个变种,用于在未完全排序的数组中找到第k小的元素。线性时间选择算法的平均时间复杂度为O(n),但最坏情况下的时间复杂度仍然是O(n^2)。通过随机选择基准点(pivot),可以在一定程度上避免最坏情况的发生。

以下是线性时间选择算法的一个C++实现示例:

#include <iostream>   
#include <stdlib.h>  
#include <time.h>  using namespace std;    // 分区函数,同时返回pivot的最终位置  
int Partition(int a[], int low, int high){  // 初始化随机数生成器  srand((unsigned)time(0));  // 随机选择一个元素作为基准点  int key = rand() % (high - low + 1) + low;  // 交换随机选定的元素和第一个元素  int t = a[key];  a[key] = a[low];  a[low] = t;  int pivot = a[low];        // 将第一个元素作为 pivot  while (low < high){  // 从后向前扫描,找到第一个小于pivot的元素  while (low < high && a[high] >= pivot) --high;  a[low] = a[high];      // 交换  // 从前向后扫描,找到第一个大于pivot的元素  while (low < high && a[low] <= pivot) ++low;  a[high] = a[low];     // 交换  }   a[low] = pivot;           // 将 pivot 放到最终的位置  return low;  
}  // 线性时间选择算法函数,找到第k小的元素  
int Select(int a[], int low, int high, int k){  if (low < high){  // 分治  int pivotpos = Partition(a, low, high);  int j = pivotpos - low + 1; // 左边剩余元素个数  if (k <= j) return Select(a, low, pivotpos, k); // 如果第k小的元素在左边,则递归左边  else return Select(a, pivotpos + 1, high, k - j); // 否则递归右边  }  else return a[low]; // 当low == high时,返回该元素  
}  int main() {  int a[10] = {5, 3, 7, 8, 4, 2, 10, 9, 1, 6};  // 输出找到的第5小的元素(注意,索引是从0开始的)  cout << "The 5th smallest element is: " << Select(a, 0, 9, 5) << endl;   return 0;    
}

注意事项

随机数生成:每次调用Partition函数时都重新设置了随机数种子,这在实际应用中是不推荐的。更好的做法是在程序开始时(如main函数最开始处)设置一次随机数种子。

时间复杂度:虽然线性时间选择算法的平均时间复杂度为O(n),但在最坏情况下(如输入数组已经是有序的,且总是选择最小或最大元素作为pivot)会退化到O(n^2)。通过随机选择pivot可以显著降低这种情况发生的概率。

实际应用线性时间选择算法非常适用于在未排序的数组中查找第k小(或第k大)的元素,特别是在数据量较大时,比排序整个数组后再查找要高效得多。

有可能出现的特殊情况:

因为随机数本身是关于时间的伪随机数,所以可能几次都没发送变化,因此循环好几回后才结束。

在这里插入图片描述

if (k <= j) return Select(a, low, pivotpos, k); 非常重要,k<=jpivotpos 是关键,因为必须得查找到最后 low == high 才能停止。如果此时 5 的位置已经定下来了,但是 k<=jpivotpos 会将 5 继续放入下一次递归,直到最后一次 low == high 递归为止。

那为什么不能 if (k < j) return Select(a, low, pivotpos-1, k); 呢?其实是可以的,首先肯定要在上面加的代码是 if (pivotpos + 1 == K) return a[pivotpos]; 这里的 K 是全局的固定值,因为 k 会一直变动。

关于过程的呈现可以使用以下代码:

#include <iostream> 
#include <stdlib.h>
#include <time.h>using namespace std;  int a[10] = {5, 3, 7, 8, 4, 2, 10, 9, 1, 6};int Partition(int a[], int low, int high){srand((unsigned)time(0));int key = rand() % (high - low + 1) + low;cout << "key: " << key << endl;// 把随机到的元素和 low 交换 int t = a[key];a[key] = a[low];a[low] = t;int pivot = a[low];        // 将第一个元素作为 pivotwhile (low < high){while (low < high && a[high] >= pivot) --high;a[low] = a[high];      // 将小于 pivot 的元素移到低端 // 这里不能为了下一步位移,因为会导致a[high] = a[low]被错误填充 while (low < high && a[low] <= pivot) ++low;a[high] = a[low];     // 将大于 pivot 的元素移到高端} a[low] = pivot;           // 将 pivot 放到最终的位置return low;
}int Select(int a[], int low, int high, int k){if (low < high){// 分治 int pivotpos = Partition(a, low, high);int j = pivotpos - low + 1;			// 左边剩余元素个数 for (int i = 0; i <= 9; i++){  cout << a[i] << ' ';  }cout << endl;if (k <= j) return Select(a, low, pivotpos, k);	// 左半段排序 else return Select(a, pivotpos + 1, high, k - j); 	// 右半段排序}else return a[low];
}int main() {// 输出找到的第 k 小的元素 cout << Select(a, 0, 9, 5) << endl; return 0;  
}

小结:

关注我给大家分享更多有趣的知识,以下是个人公众号,提供 ||竞赛资料|| ||课程资料||
添加我的公众号即可:

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

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

相关文章

Next-ViT: 下一代视觉Transformer,用于现实工业场景中的高效部署

摘要 由于复杂的注意力机制和模型设计&#xff0c;大多数现有的视觉Transformer&#xff08;ViTs&#xff09;在实际的工业部署场景中&#xff0c;如TensorRT和CoreML&#xff0c;无法像卷积神经网络&#xff08;CNNs&#xff09;那样高效运行。这提出了一个明显的挑战&#x…

[Redis] Redis中的set和zset类型

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…

微信,手机文件管理,通过自己软件打开——手机平板电脑编程———未来之窗行业应用跨平台架构

一、手机平板IT人员编程编辑器 专为 IT 和运维人员设计的手机和平板编程编辑器&#xff0c;具有便携灵活、即时响应、适应多场景、触控便捷、资源丰富、成本较低、激发创意和数据同步方便等优点。 二、手机平板现状 目前手机和平板的现状是缺乏专门针对 IT 人员的编辑工具&a…

避免服务器安装多个mysql引起冲突的安装方法

最近工作中涉及到了数据迁移的工作. 需要升级mysql版本到8.4.2为了避免升级后服务出现异常, 因此需要保留原来的mysql,所以会出现一台服务器上运行两个mysql的情况 mysql并不陌生, 但是安装不当很容易引起服务配置文件的冲突,导致服务不可用, 今天就来介绍一种可以完美避免冲突…

COMDEL电源CX2500S RF13.56MHZ RF GENERATOR手侧

COMDEL电源CX2500S RF13.56MHZ RF GENERATOR手侧

【C++ Primer Plus习题】16.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream> #include <list> using …

采用 Redis+数据库为某互联网文化公司建立网上社区平台

目录 案例 【说明】 【问题 1】(10 分) 【问题 2】(7 分) 【问题 3】(8 分) 【答案】 【问题 1】解析 【问题 3】解析 相关推荐 案例 阅读以下关于数据库缓存的叙述&#xff0c;回答问题 1 至问题 3。 【说明】 某互联网文化发展公司因业务发展&#xff0c;需要建立网…

海思Hi3559av100 sdk开发环境搭建

SDK阐释 海思官方给的sdk布局&#xff0c;如Hi3559AV100R001C02SPC031&#xff0c;其包含编译工具、硬件设计资料、软件sdk、文档等资料&#xff0c;tree布局可以构建如下形式&#xff0c;但不是必要的。 软件sdk在 01.software中&#xff0c;这个路径下才是真正的软件代码&…

嵌入式DCMI摄像头功能调试方法

STM32F407芯片带有DCMI接口,在我们的核心板上已经将接口用18PIN的FPC座子引出。 这个接口可以接我们的OV2640接口。 本节我们开始调试摄像头。 16.1. DCMI DCMI接口是ST自己定义的接口。 Digital camera interface (DCMI),是意法半导体公司产品STM32F4xx系列芯片的快速摄像头…

Redis 篇-初步了解 Redis 持久化、Redis 主从集群、Redis 哨兵集群、Redis 分片集群

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 分布式缓存概述 2.0 Redis 持久化 2.1 RDB 持久化 2.1.1 RDB 的 fork 原理 2.2 AOF 持久化 2.3 RDB 与 AOF 之间的区别 3.0 Redis 主从集群 3.1 搭建主从集群 3.2…

使用Tortoisegit完成基于Git提交日志的代码合并

前言 日常开发中除了分支merge合并外&#xff0c;经常会用cherry-pick&#xff0c;示例&#xff1a;git cherry-pick 29d9493d,如果要进行多次代码的遴选&#xff0c;可以借助git工具TortoixeGit&#xff0c;进行多次提交的遴选。 一、Git工具及常用命令 TortoiseGit工具 T…

第二十六篇——九地篇:九种形势的应对之道

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么&#xff1f; 四、总结五、升华 一、背景介绍 地势的维度重新阐述了懂得人心的重要性&#xff0c;道久其归一为为别人。…

Village Exteriors Kit 中世纪乡村房屋场景模型

此模块化工具包就是你一直在寻找的适合建造所有中世纪幻想村庄和城市建筑所需要的工具包。 皇家园区 - 村庄外饰套件的模型和纹理插件资源包 酒馆和客栈、魔法商店、市政大厅、公会大厅、布莱克史密斯锻造厂、百货商店、珠宝商店、药店、草药师、银行、铠甲、弗莱切、马厩、桌…

【 html+css 绚丽Loading 】000051 方寸轮回矩

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f…

Stable Diffusion Fooocus批量绘图脚本

当当当挡~&#xff0c;流动传热数值计算之余发布点AIGC相关文章&#xff0c;希望大家能喜欢~ 1 Stable Diffusion各种UI分析对比 提示&#xff1a;此部分主要是对SD各种界面的简要介绍和对比&#xff0c;只关注Fooocus批量绘图的读者可直接跳到第二部分。 Stable Diffusion …

Python画笔案例-052 绘制彩色递归六边形

1、绘制彩色递归六边形 通过 python 的turtle 库绘制 彩色递归六边形&#xff0c;如下图&#xff1a; 2、实现代码 绘制彩色递归六边形&#xff0c;以下为实现代码&#xff1a; """彩色递归六边形.py """ import turtledef draw_circle(radius,…

每日一题——第九十九题

// PrintUniqueChart.cpp : 此文件包含 “main” 函数。程序执行将在此处开始并结束。 // // 设计算法&#xff0c;打印如下图案&#xff1a; #include<stdio.h>int main() {int i, j;for (i 0; i < 5; i){//每行开始先打印空格//控制每行前的空格for (int space 0…

中秋之际,唱响工体!玛丽亚·凯莉2024演唱会北京站璀璨上演

续写传奇华章 启幕音乐盛典 中秋之际&#xff0c;全国数万乐迷翘首以待的音乐盛典如约而至。时隔多年&#xff0c;传奇天后玛丽亚凯莉惊艳开唱工体&#xff01; 夜幕降临&#xff0c;圆月高悬&#xff0c;在不绝于耳的欢呼声中&#xff0c;玛丽亚凯莉以一袭流光溢彩的礼服优雅…

KVM创建的虚拟机无法访问外网

基础环境如下&#xff1a; [rootlocalhost ~]# virsh domifaddr CentOS7_YFName MAC address Protocol Address -------------------------------------------------------------------------------vnet0 52:54:00:cb:a6:0d ipv4 192.168.…

【云原生监控】Prometheus之Alertmanager报警

Prometheus之Alertmanager报警 文章目录 Prometheus之Alertmanager报警概述资源列表基础环境一、部署Prometheus服务1.1、解压1.2、配置systemctl启动1.3、监控端口 二、部署Node-Exporter2.1、解压2.2、配置systemctl启动2.3、监听端口 三、配置Prometheus收集Exporter采集的数…