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) 说明暂时不会
  • 相关阅读:
    (转)堆与堆排序
    Cantor的数表
    Sticks(poj 1011)
    Square(hdu 1511)
    Fire Net(hdu 1045)
    Lake Counting(poj 2386)
    Ants (POJ 1852)
    A + B Problem II 大数加法
    深入理解计算机系统第二版家庭作业2.66
    C++ 队列queque/deque
  • 原文地址:https://www.cnblogs.com/bigrabbit/p/2551865.html
Copyright © 2011-2022 走看看