算法导论--第七章、快速排序

1. 快速排序描述:

基于分治模式,分为分解、解决和合并三部分;

1)分解:

将数组A[p..r]划分为两个子数组A[p..q-1]和A[q+1..r],是的A[p..q-1]中每个元素都小于或等于A(q)

2)解决:

通过递归调用快速排序,对子数组A[p..q-1]和A[q+1..r]排序

3)合并:

合并两个有序的数组,A[p..r]

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3
 4 #define MaxSize 8
 5
 6 int Partition(int A[], int p, int r){
 7     int x = A[r];//将A[]中最后一个元素作为主元,基准
 8     int i = p - 1;
 9     int j;
10     int tmp;
11
12     //通过for(){...}划分数组,因为最后一个元素是主元,所以j < (r - 1 )
13     for(j = p; j < r; j++){
14         if(A[j] <= x){//元素比主元小,放到前面,并将两个元素交换位置,i <= j
15             i = i + 1;
16
17             tmp = A[i];
18             A[i] = A[j];
19             A[j] = tmp;
20     //        printf("\nSwaped: A[%d]: %d, A[%d]: %d\n", i, j, A[i], A[j]);
21         }
22     }
23     //将主元置于小于和大于两部分之间
24     tmp = A[i + 1];
25     A[i + 1] = A[r];
26     A[r] = tmp;
27
28     return (i + 1);
29 }
30
31 void QuickSort(int A[], int p, int r){
32     if(p < r){
33         int q;
34
35         q = Partition(A, p, r);
36         QuickSort(A, p, q - 1);
37         QuickSort(A, q + 1, r);
38     }
39 }
40
41 int main(){
42     int A[MaxSize] = {2, 1, 1, 1, 3, 5, 6, 4};
43     int i;
44
45     printf("A[]...\n");
46     for(i = 0; i < MaxSize; i++){
47         printf("%d ", A[i]);
48     }
49
50     QuickSort(A, 0, (MaxSize - 1));
51
52     printf("\nsorted A[]...\n");
53     for(i = 0; i < MaxSize; i++){
54         printf("%d ", A[i]);
55     }
56     printf("\n");
57
58     system("pause");
59     return 0;
60 }
时间: 2024-09-30 18:10:03

算法导论--第七章、快速排序的相关文章

算法导论第七章快速排序

一.快速排序概述 关于快速排序,我之前写过两篇文章,一篇是写VC库中的快排函数,另一篇是写了快排的三种实现方法.现在再一次看算法导论,发现对快速排序又有了些新的认识,总结如下: (1).快速排序最坏情况下的时间复杂度为O(n^2),虽然最坏情况下性能较差,但快排在实际应用中是最佳选择.原因在于:其平均性能较好,为O(nlgn),且O(nlgn)记号中的常数因子较小,而且是稳定排序. (2).快速排序的思想和合并排序一样,即分治.快排排序的分治思想体现在: a.首先从待排序的数中选择一个作为基数,

算法导论 第七章 快速排序(python)

用的最多的排序 平均性能:O(nlogn){随机化nlogn} 原地址排序 稳定性:不稳定 思想:分治 (切分左右) 学习方式:自己在纸上走一遍   def PARTITION(A,p,r): x = A[r] # 锚点 主元{大于它放一边,小于的放另一边} i = p - 1 for j in range(p,r): if A[j] <= x: i += 1 A[i],A[j] = A[j],A[i] A[i+1],A[r] = A[r],A[i+1] return i + 1 def QUI

算法导论 第7章 快速排序

快速排序在最坏情况下的时间复杂度为O(n^2),虽然在最坏情况下运行时间比较差,但是快速排序通常是用于排序的最佳选择,因为其平均性能相当好,期望的运行时间为O(nlgn),且在O(nlgn)的记号中隐含的常数因子很小. 快速排序和合并排序有相似之处,都是需要划分序列,在合并排序中,划分的过程很简单,直接选择元素序列的中间位划分位置,排序是在合并的过程中实现的,所以合并排序的合并过程很重要:相比合并排序,快速排序就没有合并的过程,只有划分,快速排序的划分过程很重要,排序是在划分的过程中实现的. /

算法导论第7章快速排序

快速排序 #include <stdint.h> #include <iostream> // QUICKSORT(A, p, r) // if p < r // q = PARTITION(A, p, r) // QUICKSORT(A, p, q - 1) // QUICKSORT(A, q + 1, r) // To sort an entire array, the initial call is QUICKSORT(A, 1, A.length) // PARTIT

算法导论 第7章 高速排序

高速排序在最坏情况下的时间复杂度为O(n^2),尽管在最坏情况下执行时间比較差,可是高速排序一般是用于排序的最佳选择.由于其平均性能相当好,期望的执行时间为O(nlgn),且在O(nlgn)的记号中隐含的常数因子非常小. 高速排序和合并排序有相似之处,都是须要划分序列,在合并排序中.划分的过程非常easy.直接选择元素序列的中间位划分位置,排序是在合并的过程中实现的,所以合并排序的合并过程非常重要.相比合并排序,高速排序就没有合并的过程.仅仅有划分,高速排序的划分过程非常重要,排序是在划分的过程

算法导论第7章___快速排序

快速排序本质上是插入排序,但是它在这个基础上增强了算法. 下面我们来分析一下快速排序: 有了前面的分析基础,我们在来看排序算法也就容易多了. public class Quick_Sort { private void quick_Sort(int []A,int left,int right){ if(left<right){ //划区比较,这个partition 第一次!得到的就是我们刚才说的2. int partition=partition(A, left, right); //实现第一

算法导论 第8章 线性时间排序

合并排序和堆排序的时间复杂度为O(nlgn),插入排序和冒泡排序的时间复杂度为O(n^2),快速排序的时间复杂度在平均情况下是O(nlgn),这些排序算法都是通过对元素进行相互比较从而确定顺序的,因此都叫比较排序. 比较排序可以看做是决策树(一个满二叉树),因为每一次比较都是一个分支.n个元素的序列,其排序的结果有 n! 种可能(n个元素的全排),所以这个决策树有 n! 个叶子结点,假设树的高度为h,则有:n! <= 2^h,所以h >= lg(n!) = Ω(nlgn).一次比较排序就是从决

算法导论 第9章 中位数和顺序统计学

/* * 算法导论 第九章 中位数和顺序统计学 * 线性时间选择元素 */ #include <iostream> #include <ctime> using namespace std; int minimum(int *arr, int len); int randomizedSelect(int *arr, int p, int r, int i); int randomizedPartition(int *arr, int p, int r); void exchange

算法导论 第13章 红黑树

二叉查找树的基本操作包括搜索.插入.删除.取最大和最小值等都能够在O(h)时间复杂度内实现,因此能在期望时间O(lgn)下实现,但是二叉查找树的平衡性在这些操作中并没有得到维护,因此其高度可能会变得很高,当其高度较高时,而二叉查找树的性能就未必比链表好了,所以二叉查找树的集合操作是期望时间O(lgn),最坏情况下为O(n). 红黑树也是一种二叉查找树,它拥有二叉查找树的性质,同时红黑树还有其它一些特殊性质,这使得红黑树的动态集合基本操作在最坏情况下也为O(lgn),红黑树通过给节点增加颜色和其它