C#,弗洛伊德-瑞文斯特(Floyd-Rivest)算法与源代码

Robert W. Floyd

1 Floyd-Rivest 算法

Floyd-Rivest 算法是一种选择算法,用于在不同元素的数组中找到第k个最小元素。它类似于快速选择算法,但在实际运行中有更好的运行时间。 和 QuickSelect 一样,该算法基于分区的思想工作。对数组进行分区后,分区元素会在正确的排序位置结束。如果数组有所有不同的元素,检索第(k+1) 个个最小元素与排序后检索第(k+1) 个个元素相同。因为完全排序是昂贵的(需要 O(N log N) 来计算),所以 Floyd-Rivest 算法利用分区在 O(N) 时间内完成相同的工作。

算法流程:

  1. 如果所考虑的数组 S 的大小足够小,则直接应用快速选择算法来获得第 K 个最小元素。这个大小是算法的任意常数,作者选择它作为 600 。
  2. 否则,使用随机抽样选择 2 个枢轴- newLeftIndex 和 newRightIndex,使得它们具有包含第 K 个最大元素的最高概率。然后,递归调用该函数,数组的左右边界现在设置为 newLeftIndex 和 newRightIndex。
  3. 像快速选择一样,在划分子阵列后,需要设置左右边界,使它们包含 K 最大的元素。 围绕 K 分割数组后,第 K 个元素处于其正确的排序位置。因此,左右边界以这样一种方式设置,即所考虑的子阵列包含数组[k]。

2 源程序

using System;
using System.Collections;
using System.Collections.Generic;

namespace Legalsoft.Truffer.Algorithm
{
    /// <summary>
    /// 弗洛伊德-瑞文斯特算法
    /// Floyd Rivest Algorithm
    /// </summary>
    public static partial class Algorithm_Gallery
    {
        private static int Sign(double x)
        {
            return (x < 0) ? -1 : (x > 0) ? 1 : 0;
        }

        private static void Swap(ref int[] arr, int i, int j)
        {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }

        private static int Floyd_Rivest(int[] arr, int left, int right, int k)
        {
            int i;
            while (right > left)
            {
                if ((right - left) > 600)
                {
                    int n = right - left + 1;
                    i = k - left + 1;
                    double z = Math.Log(n);
                    double s = 0.5 * Math.Exp(2 * z / 3);
                    double sd = 0.5 * Math.Sqrt(z * s * (n - s) / n) * Sign(i - n / 2);
                    int newLeft = Math.Max(left, (int)(k - i * s / n + sd));
                    int newRight = Math.Min(right, (int)(k + (n - i) * s / n + sd));
                    Floyd_Rivest(arr, newLeft, newRight, k);
                }

                int t = arr[k];
                i = left;
                int j = right;
                Swap(ref arr, left, k);
                if (arr[right] > t)
                {
                    Swap(ref arr, left, right);
                }

                while (i < j)
                {
                    Swap(ref arr, i, j);
                    i++;
                    j--;

                    while (arr[i] < t)
                    {
                        i++;
                    }
                    while (arr[j] > t)
                    {
                        j--;
                    }
                }
                if (arr[left] == t)
                {
                    Swap(ref arr, left, j);
                }
                else
                {
                    j++;
                    Swap(ref arr, right, j);
                }

                if (j <= k)
                {
                    left = j + 1;
                }
                if (k <= j)
                {
                    right = j - 1;
                }
            }
            return arr[k];
        }
    }
}
 

POWER BY 315SOFT.COM

3 源代码

using System;
using System.Collections;
using System.Collections.Generic;

namespace Legalsoft.Truffer.Algorithm
{
    /// <summary>
    /// 弗洛伊德-瑞文斯特算法
    /// Floyd Rivest Algorithm
    /// </summary>
    public static partial class Algorithm_Gallery
    {
        private static int Sign(double x)
        {
            return (x < 0) ? -1 : (x > 0) ? 1 : 0;
        }

        private static void Swap(ref int[] arr, int i, int j)
        {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }

        private static int Floyd_Rivest(int[] arr, int left, int right, int k)
        {
            int i;
            while (right > left)
            {
                if ((right - left) > 600)
                {
                    int n = right - left + 1;
                    i = k - left + 1;
                    double z = Math.Log(n);
                    double s = 0.5 * Math.Exp(2 * z / 3);
                    double sd = 0.5 * Math.Sqrt(z * s * (n - s) / n) * Sign(i - n / 2);
                    int newLeft = Math.Max(left, (int)(k - i * s / n + sd));
                    int newRight = Math.Min(right, (int)(k + (n - i) * s / n + sd));
                    Floyd_Rivest(arr, newLeft, newRight, k);
                }

                int t = arr[k];
                i = left;
                int j = right;
                Swap(ref arr, left, k);
                if (arr[right] > t)
                {
                    Swap(ref arr, left, right);
                }

                while (i < j)
                {
                    Swap(ref arr, i, j);
                    i++;
                    j--;

                    while (arr[i] < t)
                    {
                        i++;
                    }
                    while (arr[j] > t)
                    {
                        j--;
                    }
                }
                if (arr[left] == t)
                {
                    Swap(ref arr, left, j);
                }
                else
                {
                    j++;
                    Swap(ref arr, right, j);
                }

                if (j <= k)
                {
                    left = j + 1;
                }
                if (k <= j)
                {
                    right = j - 1;
                }
            }
            return arr[k];
        }
    }
}

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

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

相关文章

istio学习记录——VirtualService详解

上一篇使用VirtualService进行了简单的流量控制&#xff0c;并通过Gateway将流量导入到了集群内。这一篇将更加深入的介绍 VirtualService。 k8s中有service&#xff0c;service能够对流量进行负载均衡&#xff0c;那为什么istio又引入了VirtualService呢&#xff0c;因为serv…

最新IE跳转Edge浏览器解决办法(2024.2.26)

最新IE跳转Edge浏览器解决办法&#xff08;2024.2.26&#xff09; 1. IE跳转原因1.1. 原先解决办法1.2. 最新解决办法1.3. 最后 1. IE跳转原因 关于IE跳转问题是由于在2023年2月14日&#xff0c;微软正式告别IE浏览器&#xff0c;导致很多使用Windows10系统的电脑在打开IE浏览…

300分钟吃透分布式缓存-17讲:如何理解、选择并使用Redis的核心数据类型?

Redis 数据类型 首先&#xff0c;来看一下 Redis 的核心数据类型。Redis 有 8 种核心数据类型&#xff0c;分别是 &#xff1a; & string 字符串类型&#xff1b; & list 列表类型&#xff1b; & set 集合类型&#xff1b; & sorted set 有序集合类型&…

多线程与高并发(1)- 线程基础、并发特性、锁、JUC工具

文章目录 第一章、线程基础知识一、基础概念1、什么是程序&#xff1f;2、什么是进程&#xff1f;3、什么是线程&#xff1f;4、什么是线程的切换&#xff08;Context Switch&#xff09;&#xff1f;5、单核CPU 设定多线程是否有意义&#xff1f;6、工作线程数是不是设置的越大…

【Linux】部署单机项目(自动化启动)---(图文并茂详细讲解)

目录 一 准备工作 1.1 连接服务器拷贝文件 1.2 解压 二 JDK安装 2.1 配置坏境变量 2.2 查看版本 三 Tomcat(自启动) 3.1 复制启动命令的位置 3.2 添加命令相关配置文件 3.2.1 配置jdk及tomcat目录 3.2.2 添加优先级 3.3 设置自启动命令 3.4 开放端口 四 My…

行业交流 | “建筑工业化—创新型建筑技术的应用”主题沙龙

11月9日下午&#xff0c;由环同济知识经济圈发展推进领导小组办公室指导&#xff0c;上海市杨浦区科委、同济科技园核心园、同济EMBA设计协会联合主办&#xff0c;环同济发展促进会协办的“建筑工业化——创新型建筑技术的应用”主题沙龙在我园区顺利举办。优积建筑科技发展(上…

32单片机基础:TIM定时中断

STM32中功能最强大&#xff0c;结构最复杂的一个外设——定时器 因为定时器的内容很多&#xff0c;所以本大节总共分为4个部分&#xff0c;8小节。 第一部分&#xff1a;主要讲定时器基本的定时功能,也就是定一个时间&#xff0c;然后让定时器每隔这个时间产生一个中断&#…

鸿蒙ArkTs开发WebView问题总结

1. 加载WebView页面报错"Can not read properties of null (reading getltem)" 解决: 在加载webview的controller中加入.domStorageAccess(true) build() {Column() {Row().width(100%).height(50rpx)Web({ src: src, controller: this.controller }).javaScriptAc…

【2.3深度学习开发任务实例】(1)神经网络模型的特点【大厂AI课学习笔记】

从本章开始&#xff0c;我把标题的顺序变了一下&#xff0c;大厂AI课笔记&#xff0c;放到后面。因为我发现App上&#xff0c;标题无法显示完全。 从本章开始&#xff0c;要学习深度学习开发任务的全部过程了。 我们将通过小汽车识别赛道上的标志牌&#xff0c;给出检测框&am…

Leetcoder Day25| 回溯part05:子集+排列

491.递增子序列 给定一个整型数组, 你的任务是找到所有该数组的递增子序列&#xff0c;递增子序列的长度至少是2。 示例: 输入:[4, 7, 6, 7]输出: [[4, 6], [4, 7], [4, 6, 7], [6, 7], [7,7], [4,7,7]] 说明: 给定数组的长度不会超过15。数组中的整数范围是 [-100,100]。给定数…

Camtasia 2023 v23.4.2.51146 (x64) 中文激活授权版(附安装教程+激活补丁) 喀秋莎(屏幕录制剪辑) 常用快捷键

目录 功能特性 常用快捷键 一、关于文件设置 二、关于编辑设置 三、关于视图设置 四、关于录制设置 破解说明 Camtasia 2023免费版是一款由TechSmith公司官方进行汉化推出的最新版本&#xff0c;该软件集屏幕录制和视频剪辑功能于一体的软件&#xff0c;提供屏幕录制、区域录…

Maya笔记 设置工作目录

Maya会把素材场景等自动保存在工作目录里&#xff0c;我们可以自己定义工作目录 步骤1 创建workspace.mel文件 文件/设置项目 ——>选择一个文件夹&#xff0c;点击设置——>创建默认工作区 这一个后&#xff0c;可以在文件夹里看到.mel文件 步骤2 自动创建文件夹…

Groovy(第九节) Groovy 之单元测试

JUnit 利用 Java 对 Song 类进行单元测试 默认情况下 Groovy 编译的类属性是私有的,所以不能直接在 Java 中访问它们,必须像下面这样使用 setter: 编写这个测试用例余下的代码就是小菜一碟了。测试用例很好地演示了这样一点:用 Groovy 所做的一切都可以轻易地在 Java 程序…

使用 Debezium 和 RisingWave 对 MongoDB 进行持续分析

MongoDB 和流式 Join 的挑战 谷歌趋势显示&#xff0c;有关 MongoDB 流式计算的搜索率不断上升 作为一种操作型数据库&#xff0c;MongoDB 在提供快速数据操作和查询性能方面表现十分出色。然而&#xff0c;在维护实时视图或执行流处理任务的内置支持方面&#xff0c;它确实存…

uni-app之android原生插件开发

官网 uni小程序SDK 一 插件简介 1.1 当HBuilderX中提供的能力无法满足App功能需求&#xff0c;需要通过使用Andorid/iOS原生开发实现时&#xff0c;可使用App离线SDK开发原生插件来扩展原生能力。 1.2 插件类型有两种&#xff0c;Module模式和Component模式 Module模式&…

51单片机 wifi连接

一、基本概念 ESP8266是一款集成了WiFi功能的高性能芯片&#xff0c;广泛应用于物联网设备、智能家居、传感器网络等领域。以下是ESP8266的详细讲解&#xff1a; 1. 功能特点&#xff1a;ESP8266集成了TCP/IP协议栈&#xff0c;支持STA&#xff08;Station&#xff09;和AP&am…

OpenAI划时代大模型——文本生成视频模型Sora作品欣赏(八)

Sora介绍 Sora是一个能以文本描述生成视频的人工智能模型&#xff0c;由美国人工智能研究机构OpenAI开发。 Sora这一名称源于日文“空”&#xff08;そら sora&#xff09;&#xff0c;即天空之意&#xff0c;以示其无限的创造潜力。其背后的技术是在OpenAI的文本到图像生成模…

虚拟机安装+固定ip地址

一、下载CentOS 二、安装CentOS 1、打开你的VMware Workstation Pro&#xff0c;并点击“创建新的虚拟机” 2、点选典型(推荐)(T)&#xff0c;并点击“下一步” 3、点选稍后安装操作系统(S)&#xff0c;并点击“下一步” 4、点选Linux&#xff0c;并点击“下一步” 6、点击“…

tomcat下载搭建

环境&#xff1a;centos7 打开环境先测试是否有网 ping www.baidu.com 在使用ifconfig命令查询ip地址 准备工作做好打开tomcat官网Apache Tomcat - Apache Tomcat 8 Software Downloads 找到tomcat8安装 复制链接 打开centos安装wget 进入到 /usr/local目录中 cd /usr/loc…

SpringMVC 学习(八)之文件上传与下载

目录 1 文件上传 2 文件下载 1 文件上传 SpringMVC 对文件的上传做了很好的封装&#xff0c;提供了两种解析器。 CommonsMultipartResolver&#xff1a;兼容性较好&#xff0c;可以兼容 Servlet3.0 之前的版本&#xff0c;但是它依赖了 commons-fileupload …