`
wx1568520008
  • 浏览: 20420 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

关于快速排序

 
阅读更多

    假设我们现在对“6  1  2 7  9  3  4  5 10  8”这个10个数进行排序。首先在这个序列中随便找一个数作为基准数(不要被这个名词吓到了,就是一个用来参照的数,待会你就知道它用来做啥的了)。为了方便,就让第一个数6作为基准数吧。接下来,需要将这个序列中所有比基准数大的数放在6的右边,比基准数小的数放在6的左边,类似下面这种排列。

       3  1  2 5  4  6  9 7  10  8

     在初始状态下,数字6在序列的第1位。我们的目标是将6挪到序列中间的某个位置,假设这个位置是k。现在就需要寻找这个k,并且以第k位为分界点,左边的数都小于等于6,右边的数都大于等于6。 回忆一下冒泡排序,是如何通过“交换”,一步步让每个数归位的。此时你也可以通过“交换”的方法来达到目的。具体是如何一步步交换呢?怎样交换才既方便又节省时间呢?

    方法其实很简单:分别从初始序列“6  1  2 7  9  3  4  5 10  8”两端开始“探测”。先从右往左找一个小于6的数,再从左往右找一个大于6的数,然后交换他们。这里可以用两个变量i和j,分别指向序列最左边和最右边。我们为这两个变量起个好听的名字“哨兵i”和“哨兵j”。刚开始的时候让哨兵i指向序列的最左边(即i=1),指向数字6。让哨兵j指向序列的最右边(即j=10),指向数字8。

       首先哨兵j开始出动。因为此处设置的基准数是最左边的数,所以需要让哨兵j先出动,这一点非常重要(请自己想一想为什么)。哨兵j一步一步地向左挪动(即j--),直到找到一个小于6的数停下来。接下来哨兵i再一步一步向右挪动(即i++),直到找到一个数大于6的数停下来。最后哨兵j停在了数字5面前,哨兵i停在了数字7面前。

       现在交换哨兵i和哨兵j所指向的元素的值。交换之后的序列如下。

        6  1  2  5  9 3  4  7  10  8

         到此,第一次交换结束。接下来开始哨兵j继续向左挪动(再友情提醒,每次必须是哨兵j先出发)。他发现了4(比基准数6要小,满足要求)之后停了下来。哨兵i也继续向右挪动的,他发现了9(比基准数6要大,满足要求)之后停了下来。此时再次进行交换,交换之后的序列如下。

        6  1  2 5  4  3  9  7 10  8

        第二次交换结束,“探测”继续。哨兵j继续向左挪动,他发现了3(比基准数6要小,满足要求)之后又停了下来。哨兵i继续向右移动,糟啦!此时哨兵i和哨兵j相遇了,哨兵i和哨兵j都走到3面前。说明此时“探测”结束。我们将基准数6和3进行交换。交换之后的序列如下。

        3  1 2  5  4  6  9 7  10  8

    到此第一轮“探测”真正结束。此时以基准数6为分界点,6左边的数都小于等于6,6右边的数都大于等于6。回顾一下刚才的过程,其实哨兵j的使命就是要找小于基准数的数,而哨兵i的使命就是要找大于基准数的数,直到i和j碰头为止。现在基准数6已经归位,它正好处在序列的第6位。此时我们已经将原来的序列,以6为分界点拆分成了两个序列,左边的序列是“3  1 2  5  4”,右边的序列是“9  7  10  8”。接下来还需要分别处理这两个序列。因为6左边和右边的序列目前都还是很混乱的。不过不要紧,我们已经掌握了方法,接下来只要模拟刚才的方法分别处理6左边和右边的序列即可。现在先来处理6左边的序列现吧。

       左边的序列是“3  1  2 5  4”。请将这个序列以3为基准数进行调整,使得3左边的数都小于等于3,3右边的数都大于等于3。好了开始动笔吧。

 

    调整完毕之后的序列的顺序是:

        2  1  3  5  4

 

        OK,现在3已经归位。接下来需要处理3左边的序列“2 1”和右边的序列“5 4”。对序列“2 1”以2为基准数进行调整,处理完毕之后的序列为“1 2”,到此2已经归位。序列“1”只有一个数,也不需要进行任何处理。至此我们对序列“2 1”已全部处理完毕,得到序列是“1 2”。序列“5 4”的处理也仿照此方法,最后得到的序列如下。

        1  2  3 4  5  6 9  7  10  8

 

        对于序列“9  7  10  8”也模拟刚才的过程,直到不可拆分出新的子序列为止。最终将会得到这样的序列,如下。

        1  2  3 4  5  6  7  8 9  10

 

        到此,排序完全结束。细心的同学可能已经发现,快速排序的每一轮处理其实就是将这一轮的基准数归位,直到所有的数都归位为止,排序就结束了。

         快速排序之所比较快,因为相比冒泡排序,每次交换是跳跃式的。每次排序的时候设置一个基准点,将小于等于基准点的数全部放到基准点的左边,将大于等于基准点的数全部放到基准点的右边。这样在每次交换的时候就不会像冒泡排序一样每次只能在相邻的数之间进行交换,交换的距离就大的多了。因此总的比较和交换次数就少了,速度自然就提高了。当然在最坏的情况下,仍可能是相邻的两个数进行了交换。因此快速排序的最差时间复杂度和冒泡排序是一样的都是O(N2),它的平均时间复杂度为O(NlogN)。

转载于:https://my.oschina.net/u/4167465/blog/3089280

分享到:
评论

相关推荐

    托尼·霍尔(C. A. R. Hoare)在1962年发表的关于快速排序算法的原始论文《Quicksort》.zip

    Hoare)在1962年发表的关于快速排序算法的原始论文,题为 "Quicksort",发表在《The Computer Journal》第5卷第1期上。这篇论文是计算机科学领域的经典文献之一,首次详细介绍了快速排序算法的原理和实现方法。 在...

    关于快速排序的一些说明

    快速排序是一种高效的排序算法,由英国计算机科学家C.A.R....以上是关于C++中快速排序的基本概念、实现方式以及一些注意事项的详细说明。通过理解和掌握这些知识点,可以有效地在实际编程中应用快速排序算法。

    快速排序函数代码

    在本篇文章中,我们将深入探讨一个关于快速排序算法的具体实现——通过模板函数的形式来完成排序任务。快速排序是一种高效的排序算法,在实际应用中被广泛采用。该算法的主要优点在于其速度较快,平均时间复杂度为O...

    快速排序 数据结构 实现

    快速排序是一种高效的排序算法,由英国计算机科学家C.A.R....以上就是关于快速排序的基本原理、实现细节及其测试策略的详细说明。在实际编程中,理解和掌握快速排序的这些知识点对于编写高效的排序代码至关重要。

    C++语言快速排序算法的实现

    以下是关于快速排序算法的详细解释: 1. **基本原理**: - 快速排序的流程分为三个步骤:选择一个基准元素(pivot)、分区操作和递归排序。 - 基准元素的选择通常选取数组的第一个元素,但也可以是任意位置的元素...

    java快速排序算法实现

    快速排序是一种高效的排序算法,由英国计算机科学家C.A.R....这个压缩包中的"java快速排序算法"可能包含了更多关于快速排序的示例代码、详细解析和实践练习,可以帮助初学者更好地理解和掌握这种高效的排序算法。

    算法设计中分而治之快速排序

    《算法设计与分析》这本书可能提供了关于快速排序的详细实现和分析,包括如何选择枢轴,如何进行分区操作,以及如何进行递归调用。书中的示例程序可能涉及了递归函数的设计,以及如何在代码中体现分而治之的思想。...

    排序算法快速排序(C语言)

    以下是关于快速排序及其C语言实现的详细知识点: 1. **基本概念**: 快速排序是一种比较排序,它通过选取一个基准元素,将待排序数组分为两部分,一部分的所有元素都小于基准,另一部分的所有元素都大于或等于基准...

    数据结构快速排序和堆排序

    数据结构是计算机科学中的核心...在"DS-10103021"这个文件中,可能包含了关于快速排序和堆排序的详细实现、性能分析以及相关练习,通过学习这些内容,你可以更深入地理解这两种排序算法,并能在实际项目中灵活运用。

    快速排序的概要介绍与分析

    - **YouTube**:YouTube上有大量关于快速排序的视频教程,从基本原理到代码实现,再到优化策略,如“算法小抄”、“极客时间”等知名频道,适合视觉学习者,直观地理解算法的每一步。 #### 2. **书籍** - **《算法...

    数据结构 快速排序 输出每一趟结果

    根据给定文件的信息,我们可以总结出以下关于“数据结构 快速排序 输出每一趟结果”的知识点: ### 一、快速排序的基本概念 快速排序是一种高效的排序算法,采用分治法策略来把一个序列分为较小和较大的两个子序列...

    基于python-java-C++实现快速排序.zip

    快速排序是一种高效的排序算法,...以上就是关于快速排序在Python、Java和C++中的实现方法,这些实现都展示了快速排序的基本逻辑和操作步骤。通过深入理解并实践这些代码,可以进一步提高对排序算法的理解和编程能力。

    3. 快速排序里的学问:信息熵1

    然而,这个话题并不是关于快速排序的实现或算法细节,而是探讨了信息熵这一数学概念,并将其与快速排序中的信息处理相联系。 信息熵是信息论中的基本概念,由克劳德·香农在1948年提出,用来量化信息的不确定度。...

    冒泡排序,选择排序,插入排序,希尔排序,堆排序,归并排序,快速排序源码实现

    以下是关于"冒泡排序,选择排序,插入排序,希尔排序,堆排序,归并排序,快速排序"这七种常见排序算法的源码实现及相关知识点的详细解释: 1. **冒泡排序**:冒泡排序是一种简单的排序算法,它重复地遍历待排序的...

    用JAVA语言实现的对数据的快速排序法

    根据给定文件中的标题、描述、标签以及部分内容,可以总结并提炼出以下关于“使用JAVA语言实现的对数据的快速排序法”的相关知识点: ### 一、知识点概述 #### 标题:用JAVA语言实现的对数据的快速排序法 - **主要...

    快速,归并,堆排序算法

    以上就是关于快速排序、归并排序和堆排序的详细介绍,它们都是排序算法的重要组成部分,掌握这些算法有助于我们更好地理解和解决大规模数据排序的问题。在实验室环境中,例如“lab4_排序”,可以对这三种排序算法...

    哈工大数据结构实验5_冒泡排序与快速排序

    (1) 冒泡排序和快速排序; (2) 插入排序和希尔排序; (3) 选择排序和堆排序; (4) 递归和非递归的归并排序。 2. 产生不同规模和分布的数据,以 Excel 生成算法执行时间 T(n)关于输入规模 n 的曲线的形式,...

    字符的快速排序算法(12KB)

    快速排序是一种高效的排序算法,由英国计算机科学家C.A.R. Hoare在1960年提出。它的基本思想是分治法,通过选取一个“基准”元素,将数组分为两个子数组,使得一个子数组的所有元素都小于或等于基准,另一个子数组的...

    插入排序、选择排序、希尔排序、堆排序、冒泡、双向冒泡、快速排序、归并排序、递归的归并排序、基数排序

    以下是关于"插入排序、选择排序、希尔排序、堆排序、冒泡、双向冒泡、快速排序、归并排序、递归的归并排序、基数排序"这十大经典排序算法的详细解释: 1. 插入排序:插入排序是一种简单的排序算法,它通过构建有序...

    演示快速排序算法(12KB)

    - **README.TXT**:这是一个文本文件,通常用于提供关于软件或代码的简短说明,可能包含快速排序算法的使用方法、注意事项或其他相关信息。 - **QUIKSORT.VBP**:这是Visual Basic Project文件,保存了整个项目的...

Global site tag (gtag.js) - Google Analytics