快速排序算法和二分搜索算法

探索分治算法:从二分搜索到快速排序 本文深入探讨了分治算法的核心原理与应用。我们从二分搜索的原理入手,了解了如何高效地在有序数组中查找特定元素。随后,介绍了快速排序算法,其优化后的版本甚至能超越传奇计算机科学家艾伦·图灵的排序速度。文章不仅详细阐述了这些算法的实现过程,还通过实例分析了它们在实际问题中的应用,如如何通过分治算法解决多数元素问题,并探索了算法的时间复杂度。 阅读详情

快速排序算法和二分搜索算法

本文来自:http://blog.youkuaiyun.com/shendl/article/details/4053853     


         算法主要分为排序算法、搜索算法、图算法。图算法我用得不多,没有发言权,本文就不说了。

         排序算法中最快的是快速排序算法,搜索算法中最快的是二分搜索算法。我也最喜欢这2个算法。

         因为,它们是使用递归实现的,代码简洁清晰,效率又非常高。

         根据我的理解,算法的本质就是数学。根据输入和设定的目标,采用有限的步骤实现输出。通常,使用计算机实现的算法,都会用到循环,这样才能发挥计算机高速运算的优势。

         循环和递归是等效的,这已经被科学家所证明。数学上没有循环,只有递归的概念,因此使用递归代替循环表示算法有很多好处:

         1,  递归的代码要比循环简洁很多,也优雅很多。

         2,  递归的代码可以用数学方式建模,可以从数学角度验证其正确性。

         很多函数式语言甚至没有循环的概念和关键字,强迫你使用递归来实现循环。如,ErLang。

         递归也有一些缺点,递归使用栈来保存函数地址和参数、返回值,而栈是有一定大小的,过多的递归调用可能会造成栈溢出。

         但是,递归算法会容易转变为循环。我更欣赏递归的简洁,除非真的出现栈溢出的问题,我是不会使用循环的。

 

二分搜索算法

理论:

         二分搜索算法用于针对已排序的集合进行搜索。

         它的原理是:

         1,  找到排序数组的中间元素,如果它匹配目标值,那么就返回它在数组中的索引。

         2,  如果没有找到,那么判断中间值比目标值大还是小,

                 如果中间值比目标值大,那么就对第一个元素到middle-1的元素递归这个过程。

                 如果中间值比目标值小,那么就对middle+1到最后一个元素。

         3,  如果结束的索引小于开始的索引,返回-1,表示没有找到。

         4,  如果子集合有2个元素,那么各自比较。因为Java的整数除法会舍弃小数,如果数组只有2个元素,那么middle值一直都是第一个元素。

         经过上述的递归过程,最终将返回匹配元素的索引,或者是-1,表示找不到。 

         二分搜索算法之所以速度快,是因为它每次可以把数组切分成两半,每次递归调用都能去除一半数据,而不用匹配每一个数据。

 

代码:

         下面是代码,逻辑清楚,代码简单。

/**

     * by 沈东良/良少     http://blog.youkuaiyun.com/shendl/

     * @param array

     * @param start

     * @param end   这是最后一个元素的索引,第一次调用应该是array.length-1

     * @param value

     * @return

     */

    public static int binarySearch(int[] array,int start,int end,int value){

       int middle=(start+end)/2;

       if(end<start){

           return -1;

       }

       if(end==(start+1)){

           if(array[start]==value){

              return start;

           }else if(array[end]==value){

              return end;

           }

          

       }else if(array[middle]==value){

           return middle;

       }else if(value>array[middle]){

           return binarySearch(array,middle+1,end,value);

       }else if(value<array[middle]){

           return binarySearch(array,start,middle-1,value);

       }

       return -1;

   

    }

 

         上述代码稍加改变,就可以排序任意类型。如使用泛型,然后加上对Comparable接口的实现,即可。

 

快速排序算法

         二分搜索算法确实非常快,但是它只能用于已排序数组。如果数组未排序呢,该怎么办呢?简单,先用快速排序算法进行排序,然后再用二分搜索进行搜索。

         先排序再搜索,要比匹配每一个元素快得多。搜索引擎,数据库索引也都使用了对数据集合的排序技术,这样搜索数据才会快速。

 

理论:

         最慢,也是最容易想到的排序算法是插入排序算法:

         1,  遍历数组,找出最小的元素,把它放到第一个元素。

         2,  循环查找未排序的数组,直到整个数组排序。

         这需要2个嵌套的循环,意味着它的效率是O(n^2);

         之所以插入排序的效率如此之地,是因为要找出整个数组中最小的数据,需要遍历整个数组的元素。

          而快速排序聪明就聪明在它不查找整个数组最小、次小…的元素,而是每次仅仅把小于某个元素的值移到一边,通过迭代最终自动实现排序。这就大大节约了排序所需的计算步骤。 

         快速排序算法的理论:

         1,  如果S中的元素个数是0或者1,那么返回。

         2,  选取S中的任一元素v,称为中心点。

         3,  将S集合中的元素分为2个部分:L={小于pivot 的元素+ pivot }和R={大于或者等于pivot的元素}。

         4,  返回L和R。

         我们使用Java使用的是就地排序的方式,因此不需要返回值。

         因为Java是一种可以修改变量的语言,用函数式语言的术语来说,就是有“副作用”。我们利用这个副作用直接修改作为参数的Array,不需要返回值。

 

 

代码:

/** by 沈东良/良少     http://blog.youkuaiyun.com/shendl/

     * 快速排序,有副作用   从小到大

     * @param array

     * @param start

     * @param end这是最后一个元素的索引,第一次调用应该是array.length-1

     */

    public static void quickSort(int[] array,int start,int end){

       //有可能造成start>end   因为递归调用时j+1,可能引起j比end还大1。  另外如果数组是空的,或者输入错误也会出现这种情况

       if(end<=start){

           return;          

       }else {

           //取中间元素为中心点,然后移到最右边

           int sign=(start+end)/2;

           int tmp=array[end];

           array[end]=array[sign];

           array[sign]=tmp;

           int j=start;

           for(int i=start;i<=end-1;i++){ 

              //小于的元素和标记互换,等于的不能互换,否则会形成死循环

              if(array[i]<array[end])  {                

                   tmp=array[i];

                   array[i]=array[j];

                   array[j]=tmp;

                   j=j+1;

              }         

           }

           //把标记元素和第一个>=它的元素位置互换,这样数组就分成2个部分,一个部分比中心值小,一个部分比中心值大。

           tmp=array[j];

           array[j]=array[end];

           array[end]=tmp;

           quickSort(array,start,j);

           quickSort(array,j+1,end);

       }

    }

 

         Java的Arrays类也使用快速排序算法进行排序。但它的代码写得像天书一样。 

         提高快速排序算法执行效率的主要方法是对中心点进行检测,希望选中的中心点有更大的概率是整个数组的中值。

         我的实现中简单的选择数组中间的值作为中心点,一般来说这样的选择效率还是不错的。 

         注意上面的一项实现技术,我们使用把中心数据元素移到数组最后的方式实现了数组的就地比较。这是比较常用的技术,把数据移到数组的最前面或者最后面,方便比较数据。 

         另外,我的Java快速排序代码使用了“副作用”,而在纯函数式语言,如Haskell,ErLang中是没有“副作用”的,也就是说变量不可以重新赋值。此时就需要返回值,每次都创建新的子数组。但函数式语言的数组处理功能很强,也会做很多性能优化,因此函数式语言实现快速排序代码更加简单,没有“副作用”,也更加数学化。 

         JDK使用二分搜索和快速排序算法实现搜索和排序,足见上述两个算法的性能优势。


别再让CPU干GPU的活了:CST Studio Suite GPU加速深度调优指南(从驱动版本到任务管理器监控) 本文深入探讨了CST Studio Suite的GPU加速深度调优方法,从NVIDIA驱动版本选择到系统级资源管理,再到实时监控与瓶颈诊断技术。通过科学的驱动优化、GPU资源管理策略和高级调优技巧,显著提升仿真效率,特别适合电磁仿真工程师和硬件加速需求的专业用户。 阅读详情

相关推荐

基于Ventoy制作单个U盘引导Windows+Linux+黑苹果macOS

一款国内高手开发的一个名为Ventoy的开源多系统启动U盘制作工具,官方链接:https://www.ventoy.net/cn/index.html Ventoy 特点 不影响U盘日常普通使用 直接从ISO文件启动,无需解开 支持MBR和GPT分区格式(1.0.15+) 支持超过4GB的ISO文件 支持大部分常见操作系统, 已测试650+ 个ISO文件 不仅仅是启动,而是完整的安装过程 版本升级时数据不会丢失 Ventoy 待改进 不支持macOS和ChromeOS 准备2个空的U.

wybarcelona的博客 3万+

比二分法更快的搜索算法

速度优于二分法的搜索算法,哈希树

a353541382的博客 3880

计算机技术发展5大阶段,现阶段计算机技术应用及发展

【摘要】现代计算机科学技术的发展和普及运用,为世界各国民众基础性生产生活实践活动的组织开展路径造成了深刻影响,本文围绕现阶段计算机技术应用及发展,择取两个具体方面,展开了简要分析。【关键词】计算机技术;应用;发展改革开放以来,计算机设备的广泛运用,促进了计算机科学技术的逐步发展成熟。计算机科学技术是具备新兴表现特征的尖端应用技术,其在现代工业生产和社会生活实践活动过程中的广泛引入运用,给世界各国基...

weixin_42126677的博客 2637

比二分法更快的算法_开发面试题之二分法插入排序

二分插入排序算法是直接插入排序算法的一种优化,比起直接插入排序算法,在排序数据量比较大的时候,二分插入排序的速度就要远远高于直接插入排序。二分插入排序算法的思想是什么呢?二分插入排序通过从第二个数开始将需要排序的数分为两个部分,左边部分有序,右边部分无序,然后从右边部分第一个数开始,一个一个插入前面有序部分,与直接插入排序唯一不同的是:二分插入排序会先找出左边有序部分的中间值,然后与需要插入的值比...

weixin_39946964的博客 1292

Simulink/Requirements Toolbox 学习(一):概述

编写、导入、导出需求并使需求正式化;两种创建需求的模块:需求编辑器、需求透视;描述需求的方式:文本、图像和关键字;通过导入和导出需求文件,与第三方需求管理工具(例如 Microsoft Word、Microsoft Excel®、IBM DOORS和 IBM DOORS Next)集成。涉及模块:Requirements Eidtor、Requirements Table等;

856

手把手教你用Qt5打造二次元游戏启动器(附鸣潮同款UI源码)

本文详细介绍了如何使用Qt5框架从零开始构建一个功能完整、UI风格贴近《鸣潮》的二次元游戏启动器。教程涵盖无边框窗口、动态背景、自定义控件绘制、多线程资源加载以及下载管理等核心模块的实现,并提供了可运行的源码参考,帮助C++开发者和Qt爱好者深入掌握现代桌面应用开发技术。

weixin_29291863的博客 265

击败二分查找法——快速检索和插值检索

1.快速检索和最后回归到二分检索的快速检索 如果由于某些原因,数组长度未知,快速检索可以识别初始的搜索域。这个算法从第一个元素开始,一直加倍(*2)搜索域的上界,直到这个上界已经大于待查关键字。上界的增长如图。 之后,根据实现不同,或者采用标准的二分检索查找,或者开始另一轮的快速检索。前者可以保证O(log(n))的运行时间,后者则更接近O(n)的运行时间...

weixin_33871366的博客 307

在Ansys Simplorer中设计三相逆变器,并与Maxwell FEA耦合,实现160kW PMSM

在这篇博文中,我们将探讨如何使用设计三相逆变器,并将其与Ansys Maxwell中的电磁有限元分析模型耦合,以获得准确的系统级结果。Ansys Electronics为多域仿真提供了强大的生态系统,可实现跨各种物理领域的无缝集成。Maxwell用于电磁有限元分析 (FEA),Simplorer(Twin Builder) 用于系统级逆变器和控制器设计,Icepak用于电子热仿真。例如,我们将使用 Simplorer 介绍160 kW、8 极永磁同步电机 (PMSM)的逆变器设计过程。让我们开始吧!

jkh920184196的博客 1426

比二分查找法更好的,我的估算值查找法

我们知道,对于有序数据序列进行查找,二分查找法性能是相当好的,时间效率达到O(Log2N),但该算法其实还有些可以进行改进的地方。普通的二分查找法,直接通过折半的方式来对有序数据序列进行筛选,这种方法实际上不是十分有效。对于大多数的有序数据序列,通常分布都是比较均匀的,我们完全可以通过对数据的分布进行估算,找出合理位置,减少折半次数。基于估算数据序列折点的方式进行查找,在数据分布最好的情况下,与二

1688

InTouch历史报警与操作记录高效查询控件V4.0实战指南(一键下载即用)

本文详细介绍了InTouch历史报警与操作记录高效查询控件V4.0的实战应用。该控件针对原生AlmDbViewCtrl控件的查询效率低下、功能单一等问题,提供了智能查询、可视化统计、视图定制和一键导出Excel等强大功能,旨在帮助工程师快速处理海量历史数据,大幅提升工控运维效率。

g9h0i1的博客 960

StarRocks 面试题及参考答案详解(万字详解)

Broker Load的过程通常涉及到数据的解析、转换和加载,它支持多种数据格式,并且可以处理复杂的数据导入任务。一方面,压缩可以减少磁盘I/O操作,因为压缩后的数据占用的空间更小,需要读取的数据块数量也就更少。在StarRocks中,表数据可以被划分成多个分区,每个分区包含表的一部分数据。在传统的行存储模型中,数据是按行组织的,这意味着在执行分析查询时,系统需要读取并处理整行数据,即使很多时候只需要查询其中的少数几列。物化视图的更新可以是完全重算,也可以是增量更新,取决于物化视图的定义和数据变更的模式。

大模型大数据攻城狮的专栏 2083

力扣275-H-指数-II(比二分法效率更高的算法)

题目描述 给定一位研究者论文被引用次数的数组(被引用次数是非负整数),数组已经按照 升序排列 。编写一个方法,计算出研究者的 h 指数。 h 指数的定义: “h 代表“高引用次数”(high citations),一名科研人员的 h 指数是指他(她)的 (N 篇论文中)总共有 h 篇论文分别被引用了至少 h 次。(其余的 N - h 篇论文每篇被引用次数不多于 h 次。)" 示例: 输入: citations = [0,1,3,5,6] 输出: 3 解释: 给定数组表示研究者总共有 5 篇论文,..

yongzhouchen的博客 451

支付宝h5参数如何实现跳转?(包含相关Demo代码)

🏆本文收录于专栏,主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家!持续更新中,up!up!up!!

**My Coding Family** 3251

二分搜索算法和快速排序算法

二分搜索算法理论:         二分搜索算法用于针对已排序的集合进行搜索。它的原理是:1,  找到排序数组的中间元素,如果它匹配目标值,那么就返回它在数组中的索引。2,  如果没有找到,那么判断中间值比目标值大还是小,如果中间值比目标值大,那么就对第一个元素到middle-1的元素递归这个过程。如果中间值比目标值小,那么就对middle+1到最后一个元素。3, 

xiao_zhi_zhi的专栏 1499

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

二分搜索算法和快速排序算法的结合

时间复杂度依旧是O(nlogn)上述源代码实现了以下几点。1,可以自己定义输入。2,可以不按顺序输入。

m0_74321088的博客 271

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

二分搜索技术 合并排序 快速排序算法 线时间选择

递归与分治策略 二分搜索算法是运用分治策略的典型例子。二分搜索算法的基本思想是将n个元素分成个数大致相同的两半。取a(n/2)与x做比较。如果x=a(n/2),则找到x算法终止。如果x小于它,则只在数组a的左半部继续搜索x。如果x大于它,则指代数组a的右半部,继续搜索x,具体的C++算法可描述如下。 合并排序算法是用分治策略实现对n个元素进行排序的算法,其基本思想是将待排序元素分成大小。大致相同的两个子集合,分别对两个子集合进行排序,最终将排好序的子集和合并成要求的排好序的集合。 快速排序算法是

qq_46536449的博客 481

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

快速排序算法和二分搜索算法[转]

代码: http://blog.youkuaiyun.com/shendl/archive/2009/04/07/4053853.aspx 算法主要分为排序算法、搜索算法、图算法。图算法我用得不多,没有发言权,本文就不说了。 排序算法中最快的是快速排序算法,搜索算法中最快的是二分搜索算法。我也最喜欢这2个算法。 因为,它们是使用递归实现...

wangqiaowqo的专栏 377

【算法设计与分析】递归与分治法:二分搜索和快速排序

1、给定数组a[0 : 8]={1, 8, 12, 15, 16, 21, 30, 35, 39}。采用二分搜索算法完成下述任务: 1)查找是否有元素30,若有返回元素在数组中的位置;如没有返回无此元素。 2)查找是否有元素20,若有返回元素在数组中的位置;如没有返回无此元素。 3)当待搜索元素x=10不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j。 package test; public class text { public static void main(String[] a

qq_30260147的博客 708

【一篇文章帮你解决分治算法的所有问题】---->归并排序,快速排序,二分搜索

【一篇文章帮你解决分治算法的所有问题】--->归并排序,快速排序,二分搜索

m0_55749088的博客 1525

算法期末复习 合并排序 快速排序 二分搜索 汉罗塔 最小公共子序列问题

前言 本文记录了算法的期末复习笔记 包括快速排序 合并排序 二分搜索 汉罗塔 最小公共子序列问题 提示:以下是本篇文章正文内容,下面案例可供参考 一、合并排序是什么? 合并排序是利用分治策略对n个元素进行排序的算法。基本思想是:将待排序元素分成大小大致相同的2个子集合,分别对两个子集合进行排序,最终将排序好的子集合合并成为所要求的排好序的集合。 二、代码段 package 算法期末复习; public class mergeSort { // 合并已经排好序的几个小分区 比较分区头..

hana122的博客 456

【基础算法】快速排序+二分搜索

#include <iostream>using namespace std; //元素交换函数 void lvSwap(int *apiArray, int index1, int index2){  int temp = apiArray[index1];  apiArray[index1] = apiArray[index2];  apiArray[index2] = ...

weixin_30318645的博客 88

冒泡排序、快速排序、插入(直接插入)排序、二分搜索算法--python版

冒泡排序、快速排序、插入(直接插入)排序、二分搜索算法–python版 冒泡排序 冒泡排序: 例如 一个数组 [5,10,6,7,4,5,9] 要求从小到大排序 第一轮,从第一个数字开始往后遍历数组,和后一个数字比较,如果前一个大于后一个,就交换位置,让比较大的那个数字继续和后面的数字进行比较,直到最后就得到这个数组里面最大的数字,放在了数组最后面。 第二轮,和第一轮同理,比较到倒数第二个数字停,这就是数组中第2大的数字。 循环往复,就得到从小到大排好序的数组了。 代码如下: # 将列表中数字按照从小到大

A444477的博客 298

实验一:二分搜索与快速排序

实验一:二分搜索与快速排序 问题描述 (1)二分搜索算法 二分搜索(英语:binary search),也称折半搜索(英语:half-interval search)、对数搜索(英语:logarithmic search),是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不..

矢车菊二十七号 971

算法 | 子集数&排列树&满m叉树&二分搜索&归并排序&快速排序

这是摘要

不问过去,无论将来 725

二分搜索,合并排序及快速排序

第一章:算法引论通俗的讲,算法是解决问题的方法或过程;严格的讲,算法是满足以下性质的指令序列: 1.输入:有另个或者多个外部量作为算法的输入。 2.输出:算法产生至少一个量作为输出。 3.确定性:组成算法的每条指令是清晰的,无歧义的。 4.有限性:算法中每条指令的执行次数有限,执行每条指令的时间也有限。 程序不同与算法,程序是算法用某种程序设计语言的具体实现。 对于一个明确的数学问题,设

Wanan_Darao的博客 1317

快排和二分搜索的实验记录

#include<iostream> using namespace std; int getMiddler(int arr[],int start_,int end_); //先进行快排,将我们的数组进行排序,再进行二分搜索 void quickSort(int arr[],int startV,int endV){ if(startV<endV){ int mid=getMiddler(arr,startV,endV);

迷雾总会解 567
上一篇: Nutch命令
下一篇: 数据结构算法集
mal327
博客等级 码龄17年 155粉丝 87原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值