《算法导论》学习笔记——快速排序

快速排序

1.快速排序原理

  快速排序是一种应用很广泛的排序算法,与归并排序类似,快速排序也采用了分治策略。对于一个待排序的数组A[p...r]进行快速排序,根据分治思想,可以分为如下三个步骤:
  - 分解:数组A[p...r]被划分为两个(有可能为空)子数组A[p...q-1]和A[q+1...r],使得A[p...q-1]中的每一个元素都小于等于A[q],而A[q]也小于等于A[q+1...r]中的每一个元素。其中,计算下标q也是划分过程的一部分。
  -解决:通过递归调用快速排序,对子数组A[p...q-1]和A[q+1...r]进行快速排序。
  -合并:注意到与归并排序不同,快速排序算法中的子数组都是基于原址排序的,所以不需要合并操作,即数组A[p...r]已经排好了顺序。

  对于快速排序来说,算法的关键是找到正确的划分q,该过程的伪代码如下:

PARATITION(A, p, r)x = A[r]i = p - 1for j = p to r - 1if A[j] <= A[r]i = i + 1exchange A[i] with A[j]exchange A[i + 1] with A[r]return i + 1

  下面这张图显示了该过程。

201353493284961.png

  随着算法的执行,数组被划分为4个(可能为空)区域,如下图所示:
  1. 若p <= k <= i,则A[k] <= x;
  2. 若i+1 <= k <= j-1,则 A[k] >x;
  3. 若j < k < r,则A[k]与x的大小关系不明确;
  4. 若k = r,则A[k] = r。

201354207034113.png

2.快速排序的性能

  根据上面的分析,快速排序的运行时间依赖于对待排序数组A[p...r]的划分是否平衡,而是否划分平衡依赖于划分元素的选取,如果划分是平衡的,那么快速排序算法性能与归并排序一样;如果划分不平衡,那么快速排序的性能就接近于插入排序了,注意这里是接近,而不是相等!

  结论:平均情况下,快速排序的时间复杂度与最好划分情况下数量级一致,均为O(nlogn)注意这里是数量级一致并不意味着时间复杂度相等

3.快速排序的随机化版本

  上述的快速排序在讨论平均性能时我们假设输入数据的所有排列都是等概的。但实际情况可能并非如此,有可能出现元素大小分布极不均衡的情况。可以采用一种称为随机抽样(random sampling)的随机化技术,使主元A[r]是一个随机抽取于数组中的元素,因为主元元素是随机抽取的,我们期望在平均情况下,对输入数组的划分是比较均衡的。采取这样的操作只需要在原来的算法上改动很小的部分即可,伪代码如下:

RANDOMIZED-PARTITION(A, p, r)i = RANDOM(p, r)exchange A[r] with A[i]return PARATITION(A, p, r)

4.代码实现(C/C++,Java,Python)

  实现了快速排序最基本算法,没有考虑随机化版本=。=

C

#include <stdio.h>
#include <stdlib.h>void swap(int* a, int* b) {int tmp;tmp = *a;*a = *b;*b = tmp;
}int partition(int* array, int low, int high) {int mid, index;mid = low - 1;for(index = low; index < high; index++){if(array[index] <= array[high]) {mid += 1;swap(&array[mid], &array[index]);}}swap(&array[mid + 1], &array[high]);return mid + 1;
}void quicksort(int* array, int low, int high) {int mid;if(low < high){mid = partition(array, low, high);quicksort(array, low, mid - 1);quicksort(array, mid + 1, high);}
}int main() {int *array, length, i;printf("Enter the length of array: ");scanf("%d", &length);array = (int* )malloc(length * sizeof(int));for(i = 0; i < length; i++)scanf("%d", &array[i]);quicksort(array, 0, length - 1);for(i = 0; i< length; i++)printf("%d ", array[i]);free(array);return 0;
}

C++

#include <iostream>
#include <vector>
using namespace std;void swap(int* a, int* b) {int tmp;tmp = *a;*a = *b;*b = tmp;
}int partition(vector<int> &array, int low, int high) {int mid, index;mid = low - 1;for(index = low; index < high; index++){if(array[index] <= array[high]) {mid += 1;swap(&array[mid], &array[index]);}}swap(&array[mid + 1], &array[high]);return mid + 1;
}void quicksort(vector<int> &array, int low, int high) {int mid;if(low < high){mid = partition(array, low, high);quicksort(array, low, mid - 1);quicksort(array, mid + 1, high);}
}int main() {vector<int> array;int length, element;cout << "Enter the length of array: ";cin >> length;cout << "Enter the element of array: ";for(int i = 0; i < length; i++){cin >> element;array.push_back(element);}quicksort(array, 0, length - 1);for(int i = 0; i< length; i++)cout << array[i] << " ";return 0;
}

Java

import java.util.*;public class QuickSort {public static void display(Iterator<Integer> it) {while(it.hasNext()) {Integer element = it.next();System.out.print(element + " ");}}public static void main(String[] args) {ArrayList<Integer> array = new ArrayList<Integer>();Scanner in = new Scanner(System.in);System.out.print("Enter the length of array: ");int length = in.nextInt();System.out.print("Enter the element of array: ");for(int i = 0; i < length; i++)array.add(in.nextInt());in.close();Sort sort = new Sort(array);sort.quickSort(sort.getLow(), sort.getHigh());display(array.iterator());}
}class Sort {public Sort(ArrayList<Integer> array) {this.array = array;}public int getLow() {return 0;}public int getHigh() {return array.size() - 1;}public void quickSort(int low, int high) {int mid;if(low < high) {mid = partition(low, high);quickSort(low, mid - 1);quickSort(mid + 1, high);}}public int partition(int low, int high) {int index = low - 1;for(int i = low; i < high; i++) {if(array.get(i) <= array.get(high)) {index += 1;int[] list = swap(array.get(index), array.get(i));array.set(index, list[0]);array.set(i, list[1]);}}int[] list = swap(array.get(index + 1), array.get(high));array.set(index + 1, list[0]);array.set(high, list[1]);return index + 1;}public int[] swap(int a, int b) {int[] list = new int[2];list[0] = b;list[1] = a;return list;}private ArrayList<Integer> array;
}

Python

quickSort.py

def swap(A, i, j):tmp = A[j]A[j] = A[i]A[i] = tmpdef partition(A, low, high):mid = low - 1for i in range(low, high):if A[i] <= A[high]:mid += 1swap(A, mid, i)swap(A, mid + 1, high)return mid + 1def quickSort(A, low, high):if low < high:mid = partition(A, low, high)quickSort(A, low, mid - 1)quickSort(A, mid + 1, high)

test.py

import quickSortA = [8, 7, 3, 0, 5, 4, 2, 9, 6, 1, 4]
quickSort.quickSort(A, 0, len(A) - 1)
print A

转载于:https://www.cnblogs.com/zhxbao/p/quick_sort.html

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaTCP连接

输入输出操作 可以这样理解&#xff1a; BufferedReader/BufferedWriter使用三部曲&#xff1a; 服务器操作 import java.io.*; import java.net.ServerSocket; import java.net.Socket;public class Server {private static int port 8002;//设置端口号public static v…

Java API概述及应用

Java API概述及应用5.1_Scanner和Random的使用&#xff08;1&#xff09;Scanner&#xff08;2&#xff09;Random生成随机数5.2_ArrayList集合的使用&#xff08;1&#xff09;ArrayList的定义及限制&#xff08;2&#xff09;函数调用&#xff08;3&#xff09;字符串字符串加…

有重复数字的组合问题_带数字重复的组合和问题

有重复数字的组合问题Description: 描述&#xff1a; This is a standard interview problem to make some combination of the numbers whose sum equals to a given number using backtracking. 这是一个标准的面试问题&#xff0c;它使用回溯功能将总和等于给定数字的数字进…

第四章语法分析和语法分析程序

第四章语法分析和语法分析程序4.1_自顶向下的语法分析4.1.1_自顶向下分析过程的基本特点①消除文法直接左递归②回溯的消除及LL(1)文法4.1.2_递归下降法4.1.3_预测分析法&#xff08;也叫LL1法&#xff0c;注意分析过程中非终结符号逆序入栈&#xff09;4.2_自底向上的语法分析…

实战:RediSearch 高性能的全文搜索引擎

RediSearch 是一个高性能的全文搜索引擎,它可以作为一个 Redis Module(扩展模块)运行在 Redis 服务器上。 RediSearch 主要特性如下: 基于文档的多个字段全文索引高性能增量索引文档排序(由用户在索引时手动提供)在子查询之间使用 AND 或 NOT 操作符的复杂布尔查询可选的…

智能优化算法应用:基于法医调查算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于法医调查算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于法医调查算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.法医调查算法4.实验参数设定5.算法结果6.…

java线程的5个使用技巧

Java线程的5个使用技巧 Published: 21 Jan 2015 Category: java Java线程有哪些不太为人所知的技巧与用法&#xff1f; 萝卜白菜各有所爱。像我就喜欢Java。学无止境&#xff0c;这也是我喜欢它的一个原因。日常工作中你所用到的工具&#xff0c;通常都有些你从来没有了解过的东…

算法复习第五章贪心法

算法复习第五章贪心法概述TSP最近邻点策略最短连接策略图着色问题最小生成树&#xff08;Prim算法、Kruskal&#xff09;0-1bag问题活动安排问题多机调度概述 TSP 最近邻点策略 最短连接策略 图着色问题 最小生成树&#xff08;Prim算法、Kruskal&#xff09; 0-1bag问题 活动…

c语言putchar函数_C语言中的putchar()函数与示例

c语言putchar函数C语言中的putchar()函数 (putchar() function in C) The putchar() function is defined in the <stdio.h> header file. putchar()函数在<stdio.h>头文件中定义。 Prototype: 原型&#xff1a; int putchar(const char *string);Parameters: co…

算法复习第六章第七章

算法复习第六章第七章第六章回溯法TSP问题0-1bag问题图着色问题八皇后问题第七章分支限界法0-1bag问题TSP问题第六章回溯法 TSP问题 0-1bag问题 图着色问题 八皇后问题 第七章分支限界法 0-1bag问题 TSP问题

扫描识别系统

扫描识别系统&#xff0c;是指能够利用扫描仪进行扫描的相关文件&#xff0c;比方普通文档&#xff0c;政府公文&#xff0c;二代身份证&#xff0c;条码……等等。通过扫描仪扫描后不单单生成常见的JPG&#xff0c;PDF等格式的图像。而是利用先进的OCR技术&#xff0c;进行相关…

Python正则表达式指南上半部

本文介绍了Python对于正则表达式的支持&#xff0c;包括正则表达式基础以及Python正则表达式标准库的完整介绍及使用示例。本文的内容不包括如何编写高效的正则表达式、如何优化正则表达式&#xff0c;这些主题请查看其他教程。注意&#xff1a;本文基于Python2.4完成&#xff…

算法复习第三章分治法

算法复习第三章分治法循环日程表最近点对快速排序&#xff1a; 循环日程表 最近点对

算法复习第四章动态规划

算法复习第四章动态规划动态规划TSP问题0-1bag动态规划 TSP问题 0-1bag 最长公共子序列不考&#xff1a;

操作系统Ubuntu(实验三四)

实验三四3._实验三&#xff1a;Linux进程/线程的异步并发执行3.1_fork()函数创建子进程3.2_创建线程pthread_create();4._实验四&#xff1a;使用信号量进行互斥与同步4.1_信号量初使用&#xff08;1&#xff09;信号量简单介绍&#xff08;2&#xff09;信号量以及P、V操作的使…

实战:Redis哨兵模式(上)

上一篇我们讲了主从复制模式,它是属于 Redis 多机运行的基础,但这种模式本身存在一个致命的问题,当主节点奔溃之后,需要人工干预才能恢复 Redis 的正常使用。 例如,我们有 3 台服务器做了主从复制,一个主服务器 A 和两个从服务器 B、C,当 A 发生故障之后,需要人工把 B…

计算机网络(第四章网络层)

第四章网络层4.1_网络层提供的两种服务&#xff08;1&#xff09;虚电路服务&#xff08;2&#xff09;数据报服务4.2_网络协议4.2.1_虚拟互连网络4.2.2_分类的IP地址&#xff08;1&#xff09;分类IP地址三种分类方法IP 地址的一些重要特点4.2.3_IP地址与硬件地址4.2.4_地址解…

实战:Redis 主从同步

主从同步(主从复制)是 Redis 高可用服务的基石,也是多机运行中最基础的一个。我们把主要存储数据的节点叫做主节点 (master),把其他通过复制主节点数据的副本节点叫做从节点 (slave),如下图所示: 在 Redis 中一个主节点可以拥有多个从节点,一个从节点也可以是其他服务…

idea连接sqlserver及数据库操作

idea连接sqlserver及操作一、在连接过程中遇到的问题&#xff1a;&#xff08;1&#xff09;数据库登录失败&#xff08;2&#xff09;登录成功之后数据库端口号怎么查看二、代码连接数据库①加载驱动和连接数据库三、数据库操作连接详解链接 总体流程链接 操作实例链接 一、…

实战:Redis 集群模式(上)

Redis Cluster 是 Redis 3.0 版本推出的 Redis 集群方案,它将数据分布在不同的服务区上,以此来降低系统对单主节点的依赖,并且可以大大的提高 Redis 服务的读写性能。 Redis 将所有的数据分为 16384 个 slots(槽),每个节点负责其中的一部分槽位,当有 Redis 客户端连接集…