zoukankan      html  css  js  c++  java
  • 算法导论 第8章 线性时间排序 课后习题

    8.2-2 证明COUNTING-SORT是稳定的。

      问题解答:

      假设输入数组A[1...n],length[A]=n,数组A中有两个元素具有相同的值,下标分别为a,b(1≤a<b≤n)即A[a] = A[b]。经过计数排序运行至行7,C[A[a]] = C[A[b]]。在第9~11行中循环部分中,循环变量 i 用于指示数组A的下标,其值从 length[A] 到 1 递减遍历。由b>a可知,A[b]优先插入数组B中。在循环执行体行10、行11中,每当将一个值A[i]放入数组B位置C[A[i]]时,都要使C[A[i]]的值减1。因此,A[b]首先插入数组输出数组B中,且A[a]插入在A[b]的前一个位置上。

     
    8.2-3 在COUNTING-SORT过程中,假设第9中for循环的首部改成改写成如下形式
    9    for j ←  1 to length[A]
    证明该算法仍能正常的工作。修改后的算法是稳定的吗?
      问题解答:
        在第9~11行中循环部分中,循环变量i用于指示输入数组A的下标。循环首部的改变,仅改变数组A中元素遍历次序,即数组A中元素插入数组B的次序,从大下标优先插入变为小下标优先插入。数组A中元素插入数组B的位置为C[A[i]],只和元素的值有关,和元素的下标无关。所以修改后的算法仍然能正常的工作。
        修改后的算法,数组A中元素插入数组B的次序是小下标优先插入。如果有两个元素有相同的值,即指向C中同一个元素,则较小下标的元素优先插入数组B中,然后使指向的C中元素减1,所以较大下标的元素插入到较小下标的元素的前面。算法是不稳定的。
     
    8.3-2 下面的算法中那些是稳定的:插入排序,合并排序,堆排序和快速排序?给出一个能是任何排序算法都稳定的方法。给出的方法带来的额外时空开销是多少?
        问题解答:   
        插入排序、合并排序均是稳定的;快速排序,堆排序不稳定。
        先给每个元素增加一个域index,表示在输入数组中的索引值。元素之间的比较,先比较元素的值,若值是相等的话,需进一步比较index。每个index可用lgn位大小的整数来表示,需额外的Ω(nlgn)空间。由于增加的额外的比较次数至多和原先的比较次数相同,时间复杂度并不变。(参考答案)
     
    8.3-4说明如何在O(n)时间内,对0到n^2-1之间的n个整数进行排序。
        问题解答:    
        引理8.3 给定n个d位数,每一个数位可以取k种可能的值。如果所用的稳定排序需要Θ(n+k)的时间,基数排序算法能以Θ(d(n+k))的时间正确地对这些数进行排序。
        若采用n进制对0到n^2-1之间的数表示,需要2位数即可。由上述引理可得,基数排序的时间为Θ(d(n+k))=Θ(2(n+n)) =Θ(n) (参考答案)
        
    8.4-2 桶排序的最坏情况运行时间是什么?如果要在保持其线性运行时间的同时,使最坏情况时间为O(nlgn),要对算法做什么样的修改?
        问题解答:
        最坏情况下,即所有的输入元素均落入一个桶内,桶排序就退化为一个插入排序。而插入排序的最坏情况时间代价为Θ(n^2)。如果要在保持其线性运行时间的同时,使最坏情况时间为O(nlgn),对桶内元素排序方法更换为最坏情况为O(nlgn)的合并排序。
     
    8.4-3在单位圆内有n个点,pi=(xi, yi),使得0<xi^2 + yi^2 ≤1, i = 1,2,....,n。假设所有点是均匀分布的,亦即,某点落在圆的任一区域中的概率与该区域的面积成正比。请设计一个Θ(n)期望的算法,来根据点到原点的距离di=sqrt(xi^2 + yi^2)对n个点排序。
        问题解答:
        桶排序是把区间[0,1)区间划分成n个大小相同的子区间(即桶),且要求输入元素等可能落在任何桶中。按照桶排序的思想,把单位圆划分成n个等面积的同心环即可。
        设:输入元素有两个域x,y,分别表示横坐标和纵坐标。元素之间的大小比较是通过比较di=sqrt(xi^2 + yi^2)来判断的。
        算法伪代码:
        BUCKET-SORT'(A)
        n  ← length(A)
        for i ←1 to n
            do index  ← floor( n( A[i].x^2 + A[i].y^2 ) )
                  insert A[i] into B[index]
        for i ←1 to n
            do sort list B[i] with insertion sort
        concatenate the list B[0], B[1], ..., B[n-1] together in order
     
    思考题
    8-2 以线性时间原地排序
        假设有一个有n个数据记录组成的数组要排序,且每个记录的关键字的值为0或1。排序这样一组记录的一个算法应具备如下三个特性中的一部分。
    1)算法的运行时间为O(n)。
    2)算法是稳定的。
    3)算法是原地排序的,它可以使用除输入数组以外的固定量的存储空间。
    a)给出一个满足上述条件1和条件2的算法。
    b)给出一个满足上述条件1和条件3的算法。
    c)给出一个满足上述条件2和条件3的算法。
    d)在a)~c)中给出的算法能否用来在O(bn)时间内排序,对有b位关键字的n个记录进行基数排序?如果行,说明如何做;如果不行,说明原因。
    e)假设一个n个记录中每个的关键字都介于1到k之间。说明如何修改计数排序,使得可以在O(n+k)时间内对n个记录原地排序。除输入数组外,可另用O(k)的存储空间。你给出算法是稳定的吗?(提示:当k=3时应该如何做)
    问题解答:
    a)使用计数排序即可满足要求。
    b)由于记录的关键字的值只有两种情况(0或1),可使用类似快速排序中PARTITION将数组划分为两个区域,一区域只含关键字值均为0,另一区域关键字均为1。
        具体算法为:
        PARTITON-SORT(A)
        n ← lenght[A]
        i  ← 1
        while A[i] = 0  and i ≤ n
            do i ←  i + 1
        p← i
        i ← i - 1
        for j ← p to n
            do if A[j] = 0
                      then i ← i + 1
                               exchange A[i] ↔ A[j]
        
    c) 使用插入排序或合并排序即可满足要求
    d)
        a)算法可以,对数组元素的每一位的排序都采用计数排序即可。
        b)算法不可以,是由于快速排序算法的数组分割是不稳定的。
        c)算法也不可以,是由于插入排序和合并排序的最坏运行时间为O(n^2)。
    e) 说明暂时不会
  • 相关阅读:
    POJ 1953 World Cup Noise
    POJ 1995 Raising Modulo Numbers (快速幂取余)
    poj 1256 Anagram
    POJ 1218 THE DRUNK JAILER
    POJ 1316 Self Numbers
    POJ 1663 Number Steps
    POJ 1664 放苹果
    如何查看DIV被设置什么CSS样式
    独行DIV自适应宽度布局CSS实例与扩大应用范围
    python 从入门到精通教程一:[1]Hello,world!
  • 原文地址:https://www.cnblogs.com/bigrabbit/p/2551865.html
Copyright © 2011-2022 走看看