• CLRS2e读书笔记—Chapter9


     1 #include <stdio.h>
     2 #include <time.h>
     3 #include <stdlib.h>
     4 void swap(int* A,int i,int j)
     5 {
     6     int temp=A[i];
     7     A[i]=A[j];
     8     A[j]=temp;
     9 }
    10 int partition(int* A,int p,int r)
    11 {
    12     //pivot element
    13     int x=A[r-1];
    14     int i=p-1,j=p;
    15     for(;j!=r-1;++j)
    16     {
    17         if(A[j]<=x)
    18             swap(A,++i,j);
    19     }
    20     swap(A,++i,r-1);
    21     return i;
    22 }
    23 int randomized_partition(int* A,int p,int r)
    24 {
    25     srand((unsigned int)time(0));
    26     swap(A,rand()%r,r-1);
    27     return partition(A,p,r);
    28 }
    29 int randomized_select(int* A,int p,int r,int select)
    30 {
    31     if(p==r-1)
    32         return A[p];
    33     int q=randomized_partition(A,p,r);
    34     int k=q-p+1;
    35     if(k==select)
    36         return A[q];
    37     else if(select<k)
    38         return randomized_select(A,p,q,select);
    39     else
    40         return randomized_select(A,q+1,r,select-k);
    41 }
    42 int main(int argc, char **argv)
    43 {
    44     int A[30];
    45     int i=0;
    46     printf("Original:\n");
    47     for (;i<30;i++)
    48     {
    49         A[i]=rand();
    50         printf("%d\t",A[i]);
    51     }
    52     int result=randomized_select(A,0,30,2);
    53     printf("\nyour appointed number is %d\n",result);
    54     return 0;
    55 }

    以上是期望线性时间选择指定顺序位数值的C实现…后面那个最坏线性时间的理论意义大于实际意义,主要是主元选择方法发生了变化…另外为毛上面的select也着色了啊?

    exercises:

    9.1-1 本题的意思应该是利用9.1部分学到的成对处理,如果n是偶数,那么按顺序划分成n/2对,然后求出smaller one,组成一个新数组;如果n是奇数,那就把最后一个单独做一组;递归以上过程,直至n=2,那么就求出了最小值。次小值一定与最小值比较过,树的高度是lgn,所以…

    9.1-2 这个分析正文里面已经给出了…

    9.2-1 只有q=p或者q=i时可能产生长度为0的数组,但是i<1和i>r是绝对不会出现的,所以不可能出现在长度为0的数组递归调用的情况。

    9.2-2 概率题…忘了怎么做…

    9.2-3 Randomized-Selected'(A,p,r,i)

      while p≤r

        do if p=r

          then return A[p]

          q←Randomized-Partition(A,p,r)

          k←q-p+1

          if k=i

           then return A[q]

          else if k>i

              then r=q-1

          else do p=q+1

              i=i-k

    9.2-4 最坏情况就是每次q都选中了数组中的极大值…

    9.3-1 如果是每组7个元素:T(n)≤T($\lceil n/7 \rceil$)+T(5n/7+8)+O(n)   【4$\lceil /frac{1}{2}\lceil \frac{n}{7} \rceil -2 \rceil =\frac{2}{7}n-8】

    可以用替换法证明其消耗仍然是Θ(n),但是当每组只有3个元素的时候T(n)≤T($\lceil n/3 \rceil$)+T(2n/3+4)+O(n),用递归树展开的方法可得下界是Θ(nlgn)。

    9.3-2 大于中位数x的元素至少有3n/10-6个,代入n=140,得到36,而140/4=35,所以至少有n/4个元素小于x。

    9.3-3 主元选择方法是用9.3提供的Select,而不是以前的随机选择。

    9.3-5 主元选择直接用中位数这样就可以得到T(n)=T(n/2)+Θ(n),线性时间成立(其实就是快排的最佳情况)

    9.3-6 此题的意思不是太清楚…k分位数是吧n个元素分解成k个大小相等的集合的k-1个顺序统计量,但是我搞不清楚这里是否包括k本身,比如1 2 3的2分位数就是2,但是这是不包括2本身的…结果我搜了一下,网上的解法都是认为包括这个2的,换句话说,分别是n/k,2n/k...(k-1)n/k这几个顺序统计量。当然,存在k分位数的前提就是n mod k=0.想要将算法由O(nk)降低到O(nlgk),

    设t=n/k,首先用select算法找出分位数的中位数kt/2,对原序列以此中位数为主元进行划分,如果第i个k分位数的i<k/2,那么其对应的值存在于kt/2的左边,否则在右边,递归调用该算法直至找到所有的k中位数。参考这里

    9.3-7 求出中位数(O(n)),求出S中所有元素与该中位数的差的绝对值(O(n)),以该值为key对原序列进行计数排序(O(n)),取排序后的序列前k个数(O(1))。

    9.3-8 如果X[i]恰好是两序列合并后的中位数,那么Y中必须有n-i个小于等于X[i]的数,换言之,必有Y[n-i]≤X[i]≤Y[n-i+1]成立。使用二分法搜索满足该条件的下标,如果X[i]小于Y[n-i],那么X[i]只可能存在于右半边,否则在左半边;如果递归完成未找到符合条件的X[i],则在Y中再次寻找满足X[n-i]≤Y[i]≤X[n-i+1]的Y[i]。

    Median(X,Y)

    n←length(X)

    median←Find-Median(X,Y,n,1,n)

    if median←not-found

      then median←Find-Median(Y,X,n,1,n)

    return median

    Find-Median(A,B,n,low,high)

    if low>high

      then return not-found

    else k←$\lfloor (low+high)/2 \rfloor$

      if k=n and A[n]<B[1]

        then return A[n]

      elseif k<n and B[n-k]≤A[k]≤B[n-k+1]

        then return A[k]

      elseif A[k]<B[n-k]

        then return Find-Median(A,B,k+1,high)

      else return Find-Median(A,B,low,k-1)

    9.3-9 这是一道数学题…已知所有点的y坐标,求一条直线,使得所有点到该直线距离的和最短,设该直线为y=a,那么所求的距离和即:

    |y1-a|+|y2-a|+...+|yn-a|,最小值应该在a=(y1+y2+...+yn)/n时成立。

    problems:

    9-1 找出序列中已排序的i个最大数

    a>如果用排序的方法,最佳的渐进最坏必然是Θ(nlgn)

    b>使用最大堆,建堆的时间是O(n),抽取的时间是O(lgn),所以总的运行时间是O(n)+O(ilgn)

    c>用顺序统计算法求出第i个最大值,需要O(n)的时间,然后partition,需要O(n)的时间【在select的过程中已经进行了划分,这一步其实是不需要的】,排序需要ilgi的时间,所以总时间是O(n)+O(igi)

    9-2 加权的中位数

    b>直接排序,然后对序列的前i个元素的权值进行累加,直到恰好大于等于1/2,然后取i=i-1,A[i]即为序列的加权中位数

    c>找到序列的中位数,对左半边的权值进行累加,如果>1/2,那么对左半边进行递归(并将左半边的权值和加到该元素上),如果<1/2,而右半边>1/2,那么对右半边进行递归(权值和加到该元素上),如果满足条件,返回;如果到达边界条件n=1或n=2(取权值大的),直接计算并返回。

    d,e>数学题…表示无力。

    9-3 i<n/2时顺序统计量计算的再优化

    a>当i≥n/2时直接调用select;否则,将序列以中位数划分,取其左侧(n/2)。成对处理这n/2个数据,将较大值、较小值各组成一个序列(n/4),递归求出较小值序列中第i个顺序统计量(同时对最大值序列做对等变换),则整个序列的顺序统计量i存在于较大值或较小值序列的前i个数据之中,然后对这2i个数据组成的序列进行求出第i个顺序统计量(T(2i))。

    …感觉怎么说呢,速度提升了,但是空间占用也大幅度上升了。

    b,c,d都是数学题…表示无力。

  • 相关阅读:
    问题账户需求分析
    需求分析初学理解
    GitHub初步探索-1-使用本地代码管理工具,简化上传的过程
    软件工程概论-个人总结
    第二次冲刺-个人工作总结05
    第二次冲刺-个人工作总结04
    第二次冲刺-个人工作总结03
    第二次冲刺-个人工作总结02
    第二次冲刺-个人工作总结01
    第一次冲刺-个人工作总结10
  • 原文地址:https://www.cnblogs.com/livewithnorest/p/2664240.html
Copyright © 2020-2023  润新知