一、问题描述

内部排序是一件具有重大意义的问题,许多项目的实现中都需要用到排序。

我们知道,排序的算法有许多种,每种排序算法的时间复杂度和空间复杂度不尽相同。在解决实际问题时,往往需要根据实际需要选择排序算法。

上次实验已经讨论了希尔排序的实现及其原理,本实验重点介绍另一种排序算法——快速排序。实验中将讨论快速排序的实现及其原理。

二、数据结构——顺序结构

本实验重点在算法实现上,数据结构的思想被弱化了。在排序过程中,由于维护序关系的需要,要有交换的操作,这就破坏了ADT的物理位置的相邻反映逻辑的依次的性质,可以说这里的顺序结构只是一个二次结构。因此,本实验不对此作过多说明。

三、算法的设计和实现

1、算法描述

快速排序是一种基于比较的排序算法,算法是不稳定的。有一种形象的叫法是“挖坑+分治”排序来形容快速排序。以下简要说明其操作。

以不降序排序为例。选择序列中一个元素作为基准元素,本实验中选择的是序列区间的第一个元素。定义两个指针(这里的指针只是一个意指,不一定用c++语言中真正的指针来实现,可以是一个整型数)i和j,初始时分别指向待排序列区间的首、尾。

每一轮排序时,选择第一个元素作为基准元素,相当于在序列区间的第一个位置挖了一个坑,现在要填坑。移动j,直到Elem[j]比基准元素小,将Elem[j]挖出来填到第一个位置,这时坑就是j这个位置了;移动i,知道Elem[i]比基准元素大,将Elem[i]挖出来填到j位置,这时坑就是i这个位置了。重复上述挖坑、填坑的操作,直到i == j,结束循环。此时,将基准元素填入当前的坑里,于是在该基准元素的左侧的元素都比它小,右侧的都比它大。这时就出现了一个自相似的子结构,于是很自然地选择递归,将当前的待排序序列区间以基准元素的位置一分为二,分别重复上述过程。递归的边界是当前区间只有一个元素,平凡有序。

所谓“挖坑”上面已经提到了,所谓“分治”就是指的区间一分为二的递归过程。

2、算法复杂度分析

快速排序的时间主要耗费在划分操作上,设当前待排序区间长度为k,则共需要k-1次关键字的比较。

最坏情况是每次划分选取的基准元素都是当前区间的最小(或者最大)元素,那么划分的结果将是左边的子区间(或者右边的子区间)为空,而右边的子区间(或者左边的子区间)长度为k-1,仅比之前少一个元素。此时的时间复杂度为O(n^2)。

最好情况是每次划分选取的基准元素都正好是当前区间的中位数,划分的结果是左、右子区间元素个数大致相等,总的复杂度为O(n lgn)。

尽管快速排序的最坏情况复杂度逼近平方级别,但就平均性能而言,它是基于关键字比较的内部排序算法中速度最快的(这个网上有许多算法的时间测试,这里不再赘述),它的平均时间复杂度为O(n lgn)。

3、例子

(1)第一轮

基准元素下标 1 2 3 4 5 6 7 8 9 10
72 72 6 57 88 60 42 83 73 48 85
  48 6 57 88 60 42 83 73 48 85
  48 6 57 88 60 42 83 73 88 85
  48 6 57 42 60 42 83 73 88 85
  48 6 57 42 60 72 83 73 88 85

(2)第二轮

a)区间[1,5]

基准元素下标 1 2 3 4 5
48 48 6 57 42 60
  42 6 57 42 60
  42 6 57 57 60
  42 6 48 57 60

b)区间[7,10]

基准元素下标 7 8 9 10
83 83 73 88 85
  73 73 88 85
  73 83 88 85

c)总的序列

42 6 48 57 60 72 73 83 88 85

(3)第三轮

a)区间[1,2]

基准元素下标 1 2
42 42 6
  6 6
  6 42

b)区间[4,5]

基准元素下标 4 5
57 57 60
  57 60

c)区间[7,7],直接返回

d)区间[9,10]

基准元素下标 9 10
88 88 85
  85 85
  85 88

e)总的序列

6 42 48 57 60 72 73 83 85 88

排序完成

四、预期结果和实验中的问题

1、预期结果

程序能够正确地将一个序列按照不递减的顺序排序。下图为一个例子。

2、实验中的问题及思考

快速排序还有一些改进的版本,当然比较常见的是在选择基准元素的时候采用随机选择的方式。据研究表明,选择黄金分割点处的数作为基准元素的期望速度最快,这个我还没有仔细学习过。

附:c++源代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4
 5 using namespace std;
 6 #define MaxN 120
 7
 8 int gap[200]; //步长 2^k+1 第一项改为1
 9 int n;
10
11 template <class T> class My_list
12 {
13 private:
14     T Elem[MaxN]; //待排序的元素
15     int Len; //元素个数
16 public:
17     void Init()
18     {
19         memset(Elem, 0, sizeof(Elem));
20         Len = 0;
21     }
22     void Insert_back(T x)
23     {
24         Elem[++Len] = x;
25     }
26     void Print()
27     {
28         int i;
29         for(i = 1; i < Len; i++)
30             printf("%d ", Elem[i]);
31         printf("%d\n", Elem[i]);
32     }
33     int GetLen()
34     {
35         return Len;
36     }
37     void QuickSort(int st, int ed)
38     {
39         if(st < ed)
40         {
41             int i = st, j = ed, x = Elem[st];
42             while(i < j)
43             {
44                 while(i < j && Elem[j] > x) //找右侧比x大的元素
45                     j--;
46                 if(i < j)
47                     Elem[i++] = Elem[j];
48                 while(i < j && Elem[i] < x) //找左侧比x小的元素
49                     i++;
50                 if(i < j)
51                     Elem[j--] = Elem[i];
52             }
53             Elem[i] = x;
54             QuickSort(st, i - 1); //分治左侧区间
55             QuickSort(i + 1, ed); //分治右侧区间
56         } //if
57     }
58 };
59
60 void Read(My_list <int> &L)
61 {
62     int i, x;
63     L.Init();
64     printf("请输入需要排序的数的个数。\n");
65     scanf("%d", &n);
66     printf("请输入需要排序的数列。\n");
67     for(i = 1; i <= n; i++)
68     {
69         scanf("%d", &x);
70         L.Insert_back(x); //把x插入到最后
71     }
72 }
73
74 int main()
75 {
76     int GapNum;
77     My_list <int> L;
78     Read(L);
79     L.QuickSort(1, n);
80     printf("升序排序后的数列:\n");
81     L.Print();
82     return 0;
83 }

View Code

转载于:https://www.cnblogs.com/CQBZOIer-zyy/p/5185409.html

[数据结构]快速排序相关推荐

  1. 数据结构----快速排序

    数据结构----快速排序 原理:参考趣学数据结构 代码: #include<stdio.h> #include<stdlib.h> int quickSort(int a[], ...

  2. 用数据结构c语言写成绩排序,C语言数据结构 快速排序实例详解

    C语言数据结构 快速排序实例详解 一.快速排序简介 快速排序采用分治的思想,第一趟先将一串数字分为两部分,第一部分的数值都比第二部分要小,然后按照这种方法,依次对两边的数据进行排序. 二.代码实现 # ...

  3. 数据结构——快速排序

    系列文章:数据结构与算法系列--从菜鸟到入门 描述 快速排序是基于分治模式的,下面按分治模式来进行分析: 分解: 数组 A[p..r]被划分成两个(可能空)子数组,A[p..q-1]和 A[q+1.. ...

  4. 数据结构 快速排序的三种实现 (hoare版本 挖坑法 前后指针版本)与非递归实现

    快速排序 hoare版本 挖坑法 前后指针版本 非递归实现快速排序 快速排序:快速排序算法通过多次比较和交换来实现排序 基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另 ...

  5. 数据结构--快速排序

    快速排序是效率比较高的一种排序算法,其思想主要是递归 package mainimport "fmt"func QuickSort(left int, right int, arr ...

  6. python算法与数据结构-快速排序算法

    设定一个中间值,如下所示: low从开始位置找low是找比54小的,26比54小合格  high是从末尾位置找比54大的,如下所示: low和high重合后第一轮循环结束 第一轮递归后的结果如下所示: ...

  7. python算法与数据结构-快速排序算法(36)

    阅读目录 一.快速排序的介绍 二.快速排序的原理 三.快速排序的步骤 四.快速排序的图解 五.快速排序的python代码实现 六.快速排序的C言语代码实现 七.快速排序的时间复杂度 八.快速排序的稳定 ...

  8. 数据结构 快速排序(详解)

    快速排序 1:快速排序的思想 快速排序运用了分治的思想,即通过一趟排序 将序列分为两部分,根据选取的基准, 将比基准小的数放在基准前面,将比基准大的数放在的数放在基准后面:然后对两部分进行递归处理,以 ...

  9. 重学数据结构——快速排序,二分法查找

    每次提起快排,内心中都有点隐隐作痛. 当时腾讯的那个面试官让我写快排的前两遍排序结果,结果,我当时居然没写上来-- 这个,就是所谓的关键时刻掉链子吧,这么经典的快排都不会,真是丢死人了-- 今天在实验 ...

最新文章

  1. 初识CISCO_DHCP Server
  2. OSPF Router-ID的选择
  3. java多线程 ThreadPoolExecutor 策略的坑
  4. apache2怎么知道从哪个默认文件夹下去查找网页
  5. 深入new/delete:Operator new的全局重载
  6. nacos配置ap_Nacos 1.0.0 功能预览
  7. Linux下的TCP/IP编程----IO复用及IO复用服务端
  8. 计算机英语一级考试试题,全国计算机一级考试试题及答案
  9. 解决Error: That port is already in use.
  10. 运动目标检测单高斯背景建模
  11. JavaScript高级程序设计读书笔记(第5章引用类型之Array类型)
  12. Linux内存管理之mmap
  13. 超详细的Python实现百度云盘模拟登陆(模拟登陆进阶)
  14. 云计算怎么学?学习云计算有什么用?
  15. FLASH连连看算法分析及源代码
  16. 反向延长线段什么意思_《反向延长线》
  17. 云栖大会人脸识别闸机【技术亮点篇4】--户外闸机高20%的抗撞击能力
  18. 360校招笔试题总结3
  19. 联想笔记本查看电池寿命、近期用电情况和续航估计报告
  20. 闲置硬盘自制nas私有云_旧笔记本电脑diy nas私有云

热门文章

  1. 在python语言中下列是二进制整数_Python从菜鸟到高手(5):数字
  2. re.search中与正则表达式*结合使用的注意事项
  3. mysql大表join小表速度很慢_mysql多表join中,为什么子查询会那么慢,怎么解决-问答-阿里云开发者社区-阿里云...
  4. php调用应用程序api,使用PHP调用openAPI
  5. 信息安全与网络安全,你分清了吗?
  6. redis.conf 配置项说明
  7. Nginx映射本地静态资源时,浏览器提示跨域问题解决
  8. Angular中调用css3动画实现侧边栏的显示与隐藏
  9. Winform中双击DevExpress的TreeList的树形节点怎样获取当前节点
  10. Python中通过MyQR生成gif动图二维码