📘
Introduction_to_Algorithms
  • Introduction
  • 第6章:堆排序
    • 练习题
    • 思考题
      • 6-3 Young
  • 第7章:快速排序
    • 练习题
    • 思考题
      • 7-6 对区间的模糊排序
  • 第8章:线性时间排序
    • 练习题
      • 8.3-4 O(n)时间内对[0..n^-1]之间的n个数排序
    • 思考题
      • 8-3 排序不同长度的数据项
  • 第9章 排序和顺序统计学算法导论
    • 练习题
      • 9.1-1
      • 9.3-3 快速排序-最坏时间O(nlgn)
      • 9.3-6 nlgk时间求k分位数
      • 9.3-8 求两个数组的中位数
    • 思考题
      • 9-2-c-带权中位数
  • 第10章:栈和队列
    • 10.1 栈和队列
      • 练习题
      • 10.1-2 用一个数组实现两个栈
      • 10.1-5 双端队列
    • 10.2 链表
      • 练习题
      • 10.2-5 环形链表实现字典操作INSERT、DELETE、SEARCH
    • 10.3 指针和对象实现
      • 练习题
      • 10.3-4 紧凑的多重数组
    • 思考题
  • 第11章 散列表
  • [第12章]
    • [笔记和代码]
      • 12-2 基数树
  • 第14章
    • 笔记和代码
      • 14.3-6 MIN GAP
  • 第15章:动态规划
    • 练习题
    • 思考题
      • 15-2 整齐打印
      • 15-3 编辑距离
  • 第20章:斐波那契堆
    • 练习题
    • 思考题
  • ACM解题报告
    • 1043 八数码问题
    • 1053 Entropy
    • 1114 Piggy-Bank 完全背包
    • 1133 catalan数二维变种
    • 1166 敌兵布阵
    • 1281 棋盘游戏 二分匹配与增广链
    • 1394 Minimum Inversion Number
    • 1394 用线段树求逆序数
    • 1787 欧拉函数之在线算法
    • 2438 三分查找
    • 2473 Junk-Mail Filter 并查集的删除
    • 2824 欧拉公式之打表算法
    • 2855 Fibonacci Check-up 矩阵的应用
    • 2642 Stars 二维树状数组
    • 2888 二维RMQ
    • 3033 分组背包之每组至少选一
    • 3307 A^B = C mod D,已知A,C,D,求解B
    • 3465 Life is a Line 用归并排序求逆序数
    • 3483 A Very Simple Problem 数论+矩阵的应用
    • 3518 后缀数组
    • 3579 中国剩余定理(ACM/不互质的情况)
    • 后缀数组
    • B-树
    • 排序算法总结
Powered by GitBook
On this page
  • 7-1 Hoare划分的正确性
  • 7-2 对快速排序算法的另一种分析
  • 7-3 Stooge排序
  • 7-4 快速排序中的堆栈深度
  • 7-5 “三数取中”划分
  1. 第7章:快速排序

思考题

7-1 Hoare划分的正确性

a)

A = {13 19 9 5 12 8 7 4 11 2 6 21}

==> A = {6 19 9 5 12 8 7 4 11 2 13 21}

==> A = {6 2 9 5 12 8 7 4 11 19 13 21}

==> A = {4 2 9 5 12 8 7 6 11 19 13 21}

==> A = {4 2 5 9 12 8 7 6 11 19 13 21}

==> A = {2 4 5 9 12 8 7 6 11 19 13 21}

==> A = {2 4 5 6 12 8 7 9 11 19 13 21}

==> A = {2 4 5 6 7 8 12 9 11 19 13 21}

==> A = {2 4 5 6 7 8 9 12 11 19 13 21}

==> A = {2 4 5 6 7 8 9 12 11 13 19 21}

b)自己写的,很乱,凑合看吧

主要证明以下几点:

(1)do repeat j<-j-1 until A[j]<=x

这个repeat中,第一次执行L6时p<=j<=r,最后一次执行L6时p<=j<=r

证明:

1.第一次执行L6时p<=j<=r。为了区分,j'=j-1,L6中的j用j'表示。

第一次进入while循环时,j=r+1,j'=r,满足p<=j<=r。

若不是第一次进入while循环,j<=r且j>p。因为如果j=p,在上一次while循环中L9的if不能通过,已经return了。因此p<=j<r-1,满足p<=j<=r。

2.最后一次执行L6时p<=j<=r,即要证明在A[p..r]中存在j'满足j'<=j且A[j]<=x

若第一次进入while循环,j'=p满足条件

若不是第一次进入while循环,在上一次while循环中交换过去的那个元素满足条件

(2)do repeat i=x

这个repeat中,第一次执行L8时p<=i<=r,最后一次执行L8时p<=i<=r

证明:证明方法与(1)类似

c)根据b可知返回值p<=j<=r,这里只需证明j!=r

若A[r]>x,L5和L6的循环不会在j=r时停止,因此返回值j!=r

若A[r]<=x,只有在第一次进入while循环时,L5和L6的循环在j=r时停止。因为是第一次进入while循环,A[i]=A[p]=x,L7和L8的循环会在i=p时停止。显然会第二次进入while循环,此时j<r,因此返回值j!=r

d)题目写错了,应该是A[p..j]中的每个元素都小于或等于A[j+1..r]中的每个元素

结束时,A[p..i-1]中的元素都小于x,A[j+1..r]中的元素都大于x,命题得证

e)

int Hoare_Partition(int *A, int p, int r)    
{    
    int x = A[p], i = p - 1, j = r + 1;    
    while(true)    
    {    
        do{j--;}    
        while(A[j] > x);    
        do{i++;}    
        while(A[i] < x);    
        if(i < j)    
            swap(A[i], A[j]);    
        else return j;    
        Print(A, 12);    
    }    
}    
void Hoare_QuickSort(int  *A, int p, int r)    
{    
    if(p < r)    
    {    
        int q = Hoare_Partition(A, p, r);    
        Hoare_QuickSort(A, p, q-1);    
        Hoare_QuickSort(A, q+1, r);    
    }    
}

7-2 对快速排序算法的另一种分析

a)

               1 + 2 + …… + n       n + 1
    E[Xi] = -------------------- = -------
                    n                 2

b)后面几题表示完全看不懂

7-3 Stooge排序

void Stooge_Sort(int *A, int i, int j)  
{  
    if(A[i] > A[j])  
        swap(A[i], A[j]);  
    if(i + 1 >= j)  
        return;  
    k = (j - i + 1) / 3;  
    Stooge_Sort(A, i, j-k);  
    Stooge_Sort(A, i+k, j);  
    Stooge_Sort(A, i, j-k);  
}

a)对于数组A[i...j],STOOGE-SORT算法将这个数组划分成均等的3份,分别用A, B, C表示。

第6-8步类似于冒泡排序的思想。它进行了两趟:

第一趟的第6-7步将最大的1/3部分交换到C

第二趟的第8步将除C外的最大的1/3部分交换到B

剩余的1/3位于A,这样的话整个数组A[i...j]就有序了。

b)比较容易写出STOOGE-SORT最坏情况下的运行时间的递归式

T(n) = 2T(2n/3)+Θ(1)

由主定律可以求得T(n)=n^2.71

c)各种排序算法在最坏情况下的运行时间分别为:

插入排序、快速排序:Θ(n^2)

堆排序、合并排序:Θ(nlgn)

相比于经典的排序算法,STOOGE-SORT算法具有非常差的性能,这几位终生教授只能说是浪得虚名了^_^

7-4 快速排序中的堆栈深度

a)

void QuickSort2(int *A, int p, int r)
{
    while(p < r)
    {
        int q = Partition(A, int p, r);
        QuickSort2(A, p, q-1);
        p = q + 1;
    }
}

b) A = {1, 2, 3, 4, 5, 6} c)

void QuickSort3(int *A, int p, int r)
{
    while(p < r)
    {
        int q = Partition(A, int p, r);
        if(r-q > q-p)
        {
            QuickSort3(A, p, q-1);
            p = q + 1;
        }
        else
        {
            QuickSort3(A, q+1, r);
            r = q - 1;
        }
    }
}

7-5 “三数取中”划分

a)n个数任意取三个不同的数的取法共有C(3,n)种

若要x=A'[i],必须在A'[1..i-1]中取一个数,在A'[i+1..n]中取一个数取法共(i-1)*(n-i)

      (i-1) * (n-i)     6 * (i-1) * (n-i)
pi = --------------- = -------------------
         C(3,n)         n * (n-1) * (n-2)

b)在一般实现中,pi=1/n。

n->正无穷时,极限为0。

在这种实现中,当i=(n+1)/2时,

      3(n-1)
pi = ---------,当n->正无穷时,极限为0
      2n(n-2)

c)遇到这种数学题就没办法了,哎,以前数学没学好

d)不会求

Previous练习题Next7-6 对区间的模糊排序

Last updated 5 years ago

以下内容转

http://blog.csdn.net/zhanglei8893
附自己写的程序