`
这些年
  • 浏览: 400391 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

zy19982004--数据结构与算法学习五:快速排序

 
阅读更多

一. 排序方法

  1. 快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。
  2. 分治法的基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题。递归地解这些子问题,然后将这些子问题的解组合为原问题的解。原排序数组data[0...n]。
    1. 分解:在data[low..high]中任选一个记录作为基准(pivot),以此基准将当前无序区划分为左、右两个较小的子区间data[low..pivotpos-1]和data[pivotpos+1..high],并使左边子区间中所有记录的关键字均小于等于基准记录pivot,右边的子区间中所有记录的关键字均大于等于pivot,而基准记录pivot则位于正确的位置(pivotpos)上,它无须参加后续的排序。
    2. 递归:data[low..high]被划分为两个子区间data[low..pivotpos-1)和data[pivotpos+1..high],而每个子区间采用相同的方法再次划分为两个子区间...
    3. 组合:因为当"求解"步骤中的两个递归调用结束时,其左、右两个子区间已有序。对快速排序而言,"组合"步骤无须做什么,可看作是空操作。

 

二. 动画演示

     http://student.zjzk.cn/course_ware/data_structure/web/flashhtml/kuaisupaixu.htm

 

三.Java代码  

Java代码  收藏代码
  1. /** 
  2.  * 快速排序 
  3.  * @param data 
  4.  * @param low data最小下标 
  5.  * @param high data最大下标 
  6.  * @return 
  7.  */  
  8. public static int[] quickSort(int[] data, int low, int high) {  
  9.     // 对data[low..high]快速排序  
  10.     int pivotpos; // 划分后的基准记录的位置  
  11.     if (low < high) {// 仅当区间长度大于1时才须排序  
  12.         pivotpos = partition(data, low, high); // 对data[low..high]做划分  
  13.         quickSort(data, low, pivotpos - 1); // 对左区间递归排序  
  14.         quickSort(data, pivotpos + 1, high);// 对右区间递归排序  
  15.     }  
  16.     return data;  
  17. }  
  18.   
  19. /** 
  20.  * 划分算法,划分后 
  21.  * 左边子区间中所有记录的关键字均小于等于基准记录pivot 
  22.  * 右边的子区间中所有记录的关键字均大于等于pivot 
  23.  * 基准记录pivot则位于正确的位置上 ,即找到pivot在序列中的正确位置
  24.  * @param data 
  25.  * @param i 
  26.  * @param j 
  27.  * @return 
  28.  */  
  29. public static int partition(int[] data, int i, int j) {  
  30.     // 并返回基准记录的位置  
  31.     int pivot = data[i]; // 用区间的第1个记录作为基准 ,  
  32.     while (i < j) { // 从区间两端交替向中间扫描,直至i=j为止  
  33.         while (i < j && data[j] >= pivot) {  
  34.             // pivot相当于在位置i上  
  35.             j--; // 从右向左扫描,查找第1个关键字小于pivot的记录data[j]  
  36.         }  
  37.         if (i < j) // 表示找到的data[j]的关键字<pivot  
  38.             data[i++] = data[j]; // 相当于交换data[i]和data[j],交换后i指针加1  
  39.   
  40.         while (i < j && data[i] <= pivot) {  
  41.             // pivot相当于在位置j上  
  42.             i++; // 从左向右扫描,查找第1个关键字大于pivot的记录data[i]  
  43.         }  
  44.         if (i < j) // 表示找到了R[i],使data[i]>pivot  
  45.             data[j--] = data[i]; // 相当于交换data[i]和data[j],交换后j指针减1  
  46.     } // endwhile  
  47.     data[i] = pivot; // 基准记录已被最后定位  
  48.     return i;  
  49. }  

 

 

四. 时间复杂度和稳定性

  1. 最好时间复杂度
    1. 在最好情况下,每次划分所取的基准都是当前无序区的"中值"记录,划分的结果是基准的左、右两个无序子区间的长度大致相等。总的关键字比较次数:
      0(nlogn)
  2. 最坏时间复杂度
    1. 最坏情况是数组有序时,每次划分选取的基准都是当前无序区中关键字最小(或最大)的记录,划分的结果是基准左边的子区间为空(或右边的子区间为空),而划分所得的另一个非空的子区间中记录数目,仅仅比划分前的无序区中记录个数减少一个。
      因此,快速排序必须做n-1次划分,第i次划分开始时区间长度为n-i+1,所需的比较次数为n-i(1≤i≤n-1),故总的比较次数达到最大值:
      Cmax = n(n-1)/2=O(n2 )
  3. 平均时间复杂度
    1. 0(nlogn)
  4. 算法的空间复杂度:快速排序在系统内部需要一个栈来实现递归。若每次划分较为均匀,则其递归树的高度为O(lgn),故递归后需栈空间为O(lgn)。最坏情况下,递归树的高度为O(n),所需的栈空间为O(n)。
  5. 快速排序是非稳定的,例如[2,2 ,1]。
分享到:
评论

相关推荐

    快速排序 --- 非递归实现

    快速排序是一种高效的排序算法,由英国计算机科学家C.A.R....总的来说,这个压缩包提供了一个非递归实现快速排序的完整示例,通过自定义栈的数据结构,实现了快速排序算法,适用于理解和学习快速排序的非递归实现方式。

    易语言程序免安装版下载

     静态编译后的易语言可执行程序(exe)和动态链接库(dll),运行时不再依赖任何支持库文件,文件尺寸更小(相对以前的独立编译),PE结构更合理(取消了“易格式体”),加载速度更快,而且有效解决了“病毒误报”和...

    第五届蓝桥杯Java本科A组试题.

    4. **算法分析**:理解时间复杂度和空间复杂度,掌握常见排序算法(如冒泡排序、快速排序、归并排序)和查找算法(如二分查找)。 5. **异常处理**:了解Java的异常体系,学习如何使用try-catch-finally语句处理...

    java个人通讯录系统

    3. **数据结构与算法**:系统的核心是存储和操作联系人数据,这可能涉及到链表、数组、集合(如ArrayList或LinkedList)或者自定义的数据结构。可能还用到了排序算法(如快速排序、冒泡排序)来组织联系人列表。 4....

    Python numpy

    首先,我们要理解numpy的核心数据结构——`ndarray`(n-dimensional array)。与Python内置的列表不同,`ndarray`是一个同构的数据集合,即数组中的所有元素都是相同类型的,例如整型、浮点型或复数。这种结构允许...

    C程序设计(第三版)部分作业

    7. `changshi.c` - "changshi"可能指"常事"或"常见问题",这可能是一些常见编程任务的实现,比如排序算法(冒泡、选择、快速等)、搜索算法(线性、二分)或者是错误处理。 8. `smg.c` - "smg"没有明显的C语言关联...

    手把手教你一套R语言数据分析+建模 代码+注释+数据

    你可以使用`read.csv`函数加载数据到R环境中,然后使用`head()`和`str()`函数查看数据的前几行和结构。`summary()`函数则可以快速获取数据的基本统计信息。 接下来,你需要对数据进行清洗,处理缺失值(使用`is.na...

    二叉树实例

    二叉树不仅在数据结构和算法中占有重要地位,也是许多高级数据结构如AVL树、红黑树的基础,它们在数据库索引、文件系统、编译器符号表管理等领域有着广泛的应用。 总之,二叉树是计算机科学中的重要概念,熟练掌握...

    C#飞机大战案例.rar

    6. **数据结构和算法(Data Structures and Algorithms)**:游戏中的数据管理,如子弹队列、敌人列表,会用到数组、列表等数据结构。同时,碰撞检测、敌机生成等逻辑则涉及到搜索、排序等算法。 7. **资源管理...

    微机汇编作业答案.zip

    排序算法如冒泡排序、选择排序或快速排序可以被实现为汇编子程序,这需要理解和运用循环、分支结构以及栈操作。 最后,“统计个数”可能指的是统计数组元素的数量或者特定字符或字符串出现的次数。这需要熟练使用...

    JAVA核心知识点整理.rar

    在算法方面,Java可以用来实现各种经典算法,如排序(冒泡排序、插入排序、选择排序、快速排序、归并排序等)、查找(线性查找、二分查找)、图算法(深度优先搜索、广度优先搜索)、树结构(二叉树、平衡二叉树、...

Global site tag (gtag.js) - Google Analytics