第四讲 排序和顺序统计学_736002313
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
20
6.3 建堆 BUILD-MAX-HEAP的正确性
终止:过程终止时,i=0.根据循环不等式,我们 知道结点1,2,…,n中,每个都是最大堆的根, 特别的,结点1就是一个最大堆的根。 我们可以这样来计算BUILD-MAX-HEAP运行时 间的一个简单上界:每次调用MAX-HEAPFY的 时间为O(lgn),共有O(n)次调用,故运行时间为 O(nlgn)。这个界尽管是对的,但是从渐近意义 上讲不够紧确。
第四讲:排序与顺序统计学
《算法与算法复杂性》2011年春季 赵颖
排序和顺序统计学
第6章 堆排序
堆、维护堆的性质、建堆、堆排序、优先队列
第7章 快速排序
快速排序的描述、性能 快速排序的随机化版本、快速排序的分析(随机算法时介绍)
第8章 线性时间排序
比较排序算法的下界 线性时间排序: 计数排序(Counting Sort)桶排序(随机算法时介绍)
将x=1/2代入几何级数的微分来计算(A.8),则
h 0
h h 2
1/ 2
(11 / 2)
2
2
于是,BUILD-MAX-HEAP的运行时间的界为:
lg n h O h n 2 h 0 h O n h O(n) h 0 2
MAX-HEAPIFY(A,i) 1 l ← LEFT(i) 2 r ← RIGHT(i) 3 If l ≤ heap-size[A] and A[l] > A[i] 4 then largest ← l 5 else largest ← i 6 If r ≤ heap-size[A] and A[r] > A[largest] 7 then largest ← r 8 If largest ≠ i 9 then exchange A[i]↔A[largest] 10 MAX-HEAPIFY(A, largest)
30
快速排序程序
QUICKSORT(A,p,r) 1 if p <r 2 then q ←PARTITION(A,p,r) 3 QUICKSORT(A,p,q-1) 4 QUICKSORT(A,q+1,r)
Hale Waihona Puke Baidu
31
数组划分程序
PARTITION(A, p, r) 1 x ← A[r] 2 i ← p - 1 3 for j ← p to r - 1 4 do if A[j] ≤ x 5 then i ← i + 1 6 exchange A[i] ↔ A[j] 7 exchange A[i + 1] ↔ A[r] 8 return i + 1
INCREASE-KEY(S,x,k):将元素x的关键字的值增 加到k,这里k值不能小于x的原关键字的值。
25
优先级队列的操作
程序HEAP-MAXIMUM用Θ(1)时间实现了MAXIMUM HEAP-MAXIMUM(A) return A[1] 程序HEAP-EXTRACT-MAX实现了EXTRACT-MAX HEAP-EXTRACT-MAX(A) if heap-size[A]<1 then error ”heap underflow” max←A[1] A[1]←A[heap-size[A]] heap-size[A]←heap-size[A] – 1 MAX-HEAPIFY(A,1) return max
23
6.4 堆排序算法
HEAPSORT(A) 1 BUILD-MAX-HEAP(A) 2 for i length[A] downto 2 3 do exchange A[1]↔A[i] 4 heap-size[A]←heap-size[A]-1 5 MAX-HEAPIFY(A,1) HEAPSORT过程的时间代价为O(nlgn),其中 调用BUILD-MAX-HEAP的时间为O(n),n次 MAX-HEAPIFY调用中每一次的时间代价为 O(lgn)
21
6.3 建堆 BUILD-MAX-HEAP精确上界
MAX-HEAPIFY作用在高度为h的结点上的时间 为O(h),我们可以将BUILD-MAX-HEAP的代价 表达为上确界
lg n
lg n h n n h h1 O(h) O h 0 h 0 2 2
PARENT(i): i / 2 LEFT(i): 2i RIGHT(i): 2i +1
5
6.1 最大堆和最小堆
二叉堆有两种:最大堆和最小堆 对于最大堆,除了根以外的每个节点,有
A[PARENT(i)] ≥A[i] 这样,堆中的最大元素就存放在根节点中,并且在 以某一个节点为根的子树中,各节点的值都不大于 该子树根节点的值
6.1 堆
4
6.1 堆
(二叉)堆数据结构是一种数组对象,它可以被视为一颗完 全二叉树,树中每个节点和数组中存放该节点值的那个元 素对应。如果表示堆的数组为A,那么树的根为A[1]。 表示堆的数组A是一个具有两个属性的对象:length(A)是 数组中的元素个数,heap-size(A)是存放在A中的堆的元素 个数;A[heap-size(A)]之后的元素都不属于相应的堆。也 就是:Heap-size(A)<=length(A) 给定某个节点的下标i,其父节点PARENT(i),左儿子 LEFT(i)和右儿子RIGHT(i)可以表示为
12
6.3 建堆
13
6.3 建堆
14
6.3 建堆
15
6.3 建堆
16
6.3 建堆
17
6.3 建堆
18
6.3 建堆 BUILD-MAX-HEAP的正确性
为了证明BUILD-MAX-HEAP的正确性,我们使 用如下的循环不变式: 在第2~3行中for循环的每一次迭代开始时,节 点i+1,i+2,… n都是一个最大堆的根。 我们需要证明在第一次循环迭代之前,这个不 变式已为真。每次循环迭代都能保持此不变式, 并且在循环结束时这个不变式会提供一个很有 用的属性来显示程序的正确性。
7
6.2 保持堆的性质
8
6.2 保持堆的性质
9
6.2 保持堆的性质
10
6.2 保持堆的性质
当MAX-HEAPIFY作用在一棵以节点i为根的, 大小为n的子树上时,其运行时间为调整元素 A[i],A[LEFT(i)]和A[RIGHT(i)]的关系时所用时 间Θ(1),再加上对以i的某个子结点为根的子树 递归调用MAX-HEAPIFY所需的时间。i结点的 子树大小至多为2n/3,那么MAX-HEAPFY的运 行时间为: T(n) ≤ T(2n/3) + Θ(1) 根据主定理,该递归式的解为T(n) ≤ Θ(lgn)
第9章 中位数和顺序统计学
最小值和最大值 以期望线性时间做选择(随机算法时介绍) 最坏情况线性时间的选择
2
排序算法
插入排序算法:O(n2),对小规模来说是一个快速的原地排序 算法(在排序输入数组时,只有常数个元素被存放在数组以 外的空间中)。 合并排序有着较好的渐进运行时间Θ(nlgn),但是Merge程序 不在原地操作。 第六章:堆排序将在O(nlgn)时间内对n个数进行原地排序。 2 第七章:快速排序,最坏情况为 n ,平均运行时间为 Θ(nlgn),在实际中常常优于堆排序算法,象插入排序算法一 样,快速排序的代码也比较紧凑,所以它的运行时间隐含的 常数因子就很小。 以上是比较排序,第八章的决策树模型证明其下界是nlgn 其它方法:线性时间排序、计数排序、基数排序、桶排序
27
优先级队列的操作
程序MAX-HEAP-INSERT实现了INSERT操作 MAX-HEAP-INSERT(A,key) 1 heap-size[A]←heap-size[A]+1 2 A[heap-size[A]]←-∞ 3 HEAP-INCREASE-KEY(A, heap-size[A], key)
11
6.3 建堆
我们可以自底向上的用MAX-HEAPIFY来将一个 数组A[1..n]变成一个最大堆。过程BUILD-MAXHEAP对树中的每一个其他节点都调用一次 MAX-HEAPIFY。 BUILD-MAX-HEAP(A) 1 heap-size[A] ← length[A] 2 for i ← length [ A] / 2 downto 1 do MAX-HEAPIFY(A,i)
22
6.4 堆排序算法
开始时,堆排序算法先后用BUILD-MAX-HEAP 将输入数组A[1..n]构造成一个最大堆,因为数 组中最大元素在A[1],可以通过把它与A[n]互换 来达到最终正确的位置。 接下来,如果从堆中去掉结点n,可以很容易地 将A[1..n-1]建成最大堆。原来根的子女仍是最大 堆,而新的根元素可能违背了最大堆性质。这 时调用MAX-HEAPIFY(A,1)就可以保持这一性 质,在A[1..(n-1)]中构建出最大堆。
24
6.5 优先级队列
堆排序的应用:(最大/最小)优先级队列
作业调度:找出优先级最高的、插入作业、调整优先级
优先级队列是一种用来维护由一组元素构成的集合 S的数据结构,这一组元素中的每一个都有一个关 键字key。一个最大优先级队列支持以下操作:
INSERT(S,x):把元素x插入集合S MAXIMUM(S):返回S中具有最大关键字的元素 EXTRACT-MAX(S):去掉并返回S中的具有最大关键字的 元素
19
6.3 建堆 BUILD-MAX-HEAP的正确性
初始化:在第一轮循环迭代之前,i n / 2 。 结点 n / 2 1, n / 2 2 ,…,n都是叶结点, 也是平凡最大堆的根。 保持:要证明每次迭代都保持了循环不变式, 注意到结点i的子结点的编号均比i大,于是,根 据循环不变式,这些子结点都是最大堆的根。 这也是调用函数MAX-HEAPIFY(A,i),以使结点 i成为最大堆的根的前提条件。此外,MAXHEAPFY的调用保持了结点i+1,i+2,…n为最大 堆的性质。 在for循环中递减i,即为下一次迭代重新建立了 循环不等式。
28
7.1快速排序的描述
快速排序是一种排序算法,对包含n个数 的输入数组,最坏情况运行时间为n 。 虽然最坏情况运行时间比较差,但快速排 序通常是用于排序的最佳的使用选择,这 是因为其平均性能相当好:期望的运行时 间为Θ(nlgn),且Θ(nlgn)记号中隐含的常 数因子很小。 快速排序还能就地排序。
2
29
快速排序的步骤
快速排序分三个步骤
分解:数组A[p..r]被划分成两个子数组A[p..q1]和A[q+1..r],使得A[p..q-1]中的每个元素都 小于等于A(q),而且,小于A[q+1..r]中的元 素。下标q也在这个划分过程中进行计算。 解决:通过递归调用快速排序,对子数组 A[p..q-1]和A[q+1..r]排序。 合并:因为两个子数组是就地排序的,将它 们合并不需要操作,整个数组A[p..r]已排序
26
优先级队列的操作
程序HEAP-INCREASE-KEY实现了INCREASE-KEY操作。
HEAP-INCREASE-KEY(A,i,key) 1 if key<A[i] 2 then error “new key is smaller than current key” 3 A[i]←key 4 while i > 1 and A[PARENT(i)]<A[i] 5 do exchange A[i]←→A[PARENT(i)] 6 i←PARENT(i)
32
PARTITION在子数组A[p..r] 上的执行时间为Θ(n), n = r - p + 1。
快速排序图示
下图是8元素数组上运行PARTITION过程的示例
对于最小堆,除了根以外的每个节点,有
A[PARENT(i)] ≤A[i],最小堆的最小元素在跟部。
堆可以被看成一棵树,节点在堆中的高度定义为 从本节点到叶子的最长简单下降路径上边的个数。 堆的高度定义为树根的高度,为Θ(lgn)。
6
6.2 保持堆的性质
MAX-HEAPIFY是对最大堆进行操作的重要的子 程序,调整A[i]在堆中的位置,使以i为根的子树 为最大堆。重要的假设条件!
6.3 建堆 BUILD-MAX-HEAP的正确性
终止:过程终止时,i=0.根据循环不等式,我们 知道结点1,2,…,n中,每个都是最大堆的根, 特别的,结点1就是一个最大堆的根。 我们可以这样来计算BUILD-MAX-HEAP运行时 间的一个简单上界:每次调用MAX-HEAPFY的 时间为O(lgn),共有O(n)次调用,故运行时间为 O(nlgn)。这个界尽管是对的,但是从渐近意义 上讲不够紧确。
第四讲:排序与顺序统计学
《算法与算法复杂性》2011年春季 赵颖
排序和顺序统计学
第6章 堆排序
堆、维护堆的性质、建堆、堆排序、优先队列
第7章 快速排序
快速排序的描述、性能 快速排序的随机化版本、快速排序的分析(随机算法时介绍)
第8章 线性时间排序
比较排序算法的下界 线性时间排序: 计数排序(Counting Sort)桶排序(随机算法时介绍)
将x=1/2代入几何级数的微分来计算(A.8),则
h 0
h h 2
1/ 2
(11 / 2)
2
2
于是,BUILD-MAX-HEAP的运行时间的界为:
lg n h O h n 2 h 0 h O n h O(n) h 0 2
MAX-HEAPIFY(A,i) 1 l ← LEFT(i) 2 r ← RIGHT(i) 3 If l ≤ heap-size[A] and A[l] > A[i] 4 then largest ← l 5 else largest ← i 6 If r ≤ heap-size[A] and A[r] > A[largest] 7 then largest ← r 8 If largest ≠ i 9 then exchange A[i]↔A[largest] 10 MAX-HEAPIFY(A, largest)
30
快速排序程序
QUICKSORT(A,p,r) 1 if p <r 2 then q ←PARTITION(A,p,r) 3 QUICKSORT(A,p,q-1) 4 QUICKSORT(A,q+1,r)
Hale Waihona Puke Baidu
31
数组划分程序
PARTITION(A, p, r) 1 x ← A[r] 2 i ← p - 1 3 for j ← p to r - 1 4 do if A[j] ≤ x 5 then i ← i + 1 6 exchange A[i] ↔ A[j] 7 exchange A[i + 1] ↔ A[r] 8 return i + 1
INCREASE-KEY(S,x,k):将元素x的关键字的值增 加到k,这里k值不能小于x的原关键字的值。
25
优先级队列的操作
程序HEAP-MAXIMUM用Θ(1)时间实现了MAXIMUM HEAP-MAXIMUM(A) return A[1] 程序HEAP-EXTRACT-MAX实现了EXTRACT-MAX HEAP-EXTRACT-MAX(A) if heap-size[A]<1 then error ”heap underflow” max←A[1] A[1]←A[heap-size[A]] heap-size[A]←heap-size[A] – 1 MAX-HEAPIFY(A,1) return max
23
6.4 堆排序算法
HEAPSORT(A) 1 BUILD-MAX-HEAP(A) 2 for i length[A] downto 2 3 do exchange A[1]↔A[i] 4 heap-size[A]←heap-size[A]-1 5 MAX-HEAPIFY(A,1) HEAPSORT过程的时间代价为O(nlgn),其中 调用BUILD-MAX-HEAP的时间为O(n),n次 MAX-HEAPIFY调用中每一次的时间代价为 O(lgn)
21
6.3 建堆 BUILD-MAX-HEAP精确上界
MAX-HEAPIFY作用在高度为h的结点上的时间 为O(h),我们可以将BUILD-MAX-HEAP的代价 表达为上确界
lg n
lg n h n n h h1 O(h) O h 0 h 0 2 2
PARENT(i): i / 2 LEFT(i): 2i RIGHT(i): 2i +1
5
6.1 最大堆和最小堆
二叉堆有两种:最大堆和最小堆 对于最大堆,除了根以外的每个节点,有
A[PARENT(i)] ≥A[i] 这样,堆中的最大元素就存放在根节点中,并且在 以某一个节点为根的子树中,各节点的值都不大于 该子树根节点的值
6.1 堆
4
6.1 堆
(二叉)堆数据结构是一种数组对象,它可以被视为一颗完 全二叉树,树中每个节点和数组中存放该节点值的那个元 素对应。如果表示堆的数组为A,那么树的根为A[1]。 表示堆的数组A是一个具有两个属性的对象:length(A)是 数组中的元素个数,heap-size(A)是存放在A中的堆的元素 个数;A[heap-size(A)]之后的元素都不属于相应的堆。也 就是:Heap-size(A)<=length(A) 给定某个节点的下标i,其父节点PARENT(i),左儿子 LEFT(i)和右儿子RIGHT(i)可以表示为
12
6.3 建堆
13
6.3 建堆
14
6.3 建堆
15
6.3 建堆
16
6.3 建堆
17
6.3 建堆
18
6.3 建堆 BUILD-MAX-HEAP的正确性
为了证明BUILD-MAX-HEAP的正确性,我们使 用如下的循环不变式: 在第2~3行中for循环的每一次迭代开始时,节 点i+1,i+2,… n都是一个最大堆的根。 我们需要证明在第一次循环迭代之前,这个不 变式已为真。每次循环迭代都能保持此不变式, 并且在循环结束时这个不变式会提供一个很有 用的属性来显示程序的正确性。
7
6.2 保持堆的性质
8
6.2 保持堆的性质
9
6.2 保持堆的性质
10
6.2 保持堆的性质
当MAX-HEAPIFY作用在一棵以节点i为根的, 大小为n的子树上时,其运行时间为调整元素 A[i],A[LEFT(i)]和A[RIGHT(i)]的关系时所用时 间Θ(1),再加上对以i的某个子结点为根的子树 递归调用MAX-HEAPIFY所需的时间。i结点的 子树大小至多为2n/3,那么MAX-HEAPFY的运 行时间为: T(n) ≤ T(2n/3) + Θ(1) 根据主定理,该递归式的解为T(n) ≤ Θ(lgn)
第9章 中位数和顺序统计学
最小值和最大值 以期望线性时间做选择(随机算法时介绍) 最坏情况线性时间的选择
2
排序算法
插入排序算法:O(n2),对小规模来说是一个快速的原地排序 算法(在排序输入数组时,只有常数个元素被存放在数组以 外的空间中)。 合并排序有着较好的渐进运行时间Θ(nlgn),但是Merge程序 不在原地操作。 第六章:堆排序将在O(nlgn)时间内对n个数进行原地排序。 2 第七章:快速排序,最坏情况为 n ,平均运行时间为 Θ(nlgn),在实际中常常优于堆排序算法,象插入排序算法一 样,快速排序的代码也比较紧凑,所以它的运行时间隐含的 常数因子就很小。 以上是比较排序,第八章的决策树模型证明其下界是nlgn 其它方法:线性时间排序、计数排序、基数排序、桶排序
27
优先级队列的操作
程序MAX-HEAP-INSERT实现了INSERT操作 MAX-HEAP-INSERT(A,key) 1 heap-size[A]←heap-size[A]+1 2 A[heap-size[A]]←-∞ 3 HEAP-INCREASE-KEY(A, heap-size[A], key)
11
6.3 建堆
我们可以自底向上的用MAX-HEAPIFY来将一个 数组A[1..n]变成一个最大堆。过程BUILD-MAXHEAP对树中的每一个其他节点都调用一次 MAX-HEAPIFY。 BUILD-MAX-HEAP(A) 1 heap-size[A] ← length[A] 2 for i ← length [ A] / 2 downto 1 do MAX-HEAPIFY(A,i)
22
6.4 堆排序算法
开始时,堆排序算法先后用BUILD-MAX-HEAP 将输入数组A[1..n]构造成一个最大堆,因为数 组中最大元素在A[1],可以通过把它与A[n]互换 来达到最终正确的位置。 接下来,如果从堆中去掉结点n,可以很容易地 将A[1..n-1]建成最大堆。原来根的子女仍是最大 堆,而新的根元素可能违背了最大堆性质。这 时调用MAX-HEAPIFY(A,1)就可以保持这一性 质,在A[1..(n-1)]中构建出最大堆。
24
6.5 优先级队列
堆排序的应用:(最大/最小)优先级队列
作业调度:找出优先级最高的、插入作业、调整优先级
优先级队列是一种用来维护由一组元素构成的集合 S的数据结构,这一组元素中的每一个都有一个关 键字key。一个最大优先级队列支持以下操作:
INSERT(S,x):把元素x插入集合S MAXIMUM(S):返回S中具有最大关键字的元素 EXTRACT-MAX(S):去掉并返回S中的具有最大关键字的 元素
19
6.3 建堆 BUILD-MAX-HEAP的正确性
初始化:在第一轮循环迭代之前,i n / 2 。 结点 n / 2 1, n / 2 2 ,…,n都是叶结点, 也是平凡最大堆的根。 保持:要证明每次迭代都保持了循环不变式, 注意到结点i的子结点的编号均比i大,于是,根 据循环不变式,这些子结点都是最大堆的根。 这也是调用函数MAX-HEAPIFY(A,i),以使结点 i成为最大堆的根的前提条件。此外,MAXHEAPFY的调用保持了结点i+1,i+2,…n为最大 堆的性质。 在for循环中递减i,即为下一次迭代重新建立了 循环不等式。
28
7.1快速排序的描述
快速排序是一种排序算法,对包含n个数 的输入数组,最坏情况运行时间为n 。 虽然最坏情况运行时间比较差,但快速排 序通常是用于排序的最佳的使用选择,这 是因为其平均性能相当好:期望的运行时 间为Θ(nlgn),且Θ(nlgn)记号中隐含的常 数因子很小。 快速排序还能就地排序。
2
29
快速排序的步骤
快速排序分三个步骤
分解:数组A[p..r]被划分成两个子数组A[p..q1]和A[q+1..r],使得A[p..q-1]中的每个元素都 小于等于A(q),而且,小于A[q+1..r]中的元 素。下标q也在这个划分过程中进行计算。 解决:通过递归调用快速排序,对子数组 A[p..q-1]和A[q+1..r]排序。 合并:因为两个子数组是就地排序的,将它 们合并不需要操作,整个数组A[p..r]已排序
26
优先级队列的操作
程序HEAP-INCREASE-KEY实现了INCREASE-KEY操作。
HEAP-INCREASE-KEY(A,i,key) 1 if key<A[i] 2 then error “new key is smaller than current key” 3 A[i]←key 4 while i > 1 and A[PARENT(i)]<A[i] 5 do exchange A[i]←→A[PARENT(i)] 6 i←PARENT(i)
32
PARTITION在子数组A[p..r] 上的执行时间为Θ(n), n = r - p + 1。
快速排序图示
下图是8元素数组上运行PARTITION过程的示例
对于最小堆,除了根以外的每个节点,有
A[PARENT(i)] ≤A[i],最小堆的最小元素在跟部。
堆可以被看成一棵树,节点在堆中的高度定义为 从本节点到叶子的最长简单下降路径上边的个数。 堆的高度定义为树根的高度,为Θ(lgn)。
6
6.2 保持堆的性质
MAX-HEAPIFY是对最大堆进行操作的重要的子 程序,调整A[i]在堆中的位置,使以i为根的子树 为最大堆。重要的假设条件!