算法导论中,为啥合并排序的递归树的高度为lgn?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法导论中,为啥合并排序的递归树的高度为lgn?相关的知识,希望对你有一定的参考价值。

最近刚开始看算法导论,一开始将合并排序的递归过程中,假设了n是2的整数次方,那么在递归树中每次对n除以2,那么h不应该是log2 n吗,lg不是以10底吗?有点搞不通求讲解。

首先计算机科学里的lgn就是数学上的log2(n)
然后解释一下原因:
假设树的高度为h,观察前几层
第一层:cn(即cn/1),所以该层有1个数
第二层:cn/2,所以该层有2个数
……
最后一层:c(即cn/n),所以该层有n个数,也是leaves
2^h=n,h=lgn
学工程需要直觉,就不做严格的数学分析了
点个赞再走吧~ -..-
参考技术A 符号问题,这里的lg就是指log2,你的理解是正确的!在计算机科学中有些符号的使用跟我们在数学中使用的有区别。比如有时候log用来表示自然对数(以e为底数)。希望对你有帮助! 参考技术B 不才这么理解:
时间复杂度为log2N没错,
由对数中的换底公式可得: log2N = lgN/lg2,
而lg2为一个常数, 在研究复杂度时常数通常忽略(其实就是N无穷大时高阶系数和低阶项的影响太小, 可以忽略)
所以得到复杂度为lgN
纯粹个人拙见, 望计算机科学前辈指正
参考技术C lg 是以2底 ,log是以10底

算法导论归并排序

1. 分治法:分治模型在每层递归的时都有三个步骤:

  a.分解原问题为若干个子问题,这些子问题是原问题的规模较小的实例;

  b. 解决这些子问题,递归地求解各子问题的规模足够小,则直接求解;

  c. 合并这些子问题的解 成 原问题的解。

2. 归并排序算法完全遵循分治模式。

  a. 分解:分解待排序的n个元素的序列成各具 n/2 个元素的子序列

  b. 解决:使用归并排序递归地排序子序列

  c. 合并:合并两个已经排序的子序列以产生已排序的答案。

3.归并排序算法图示,实话说我没看懂第一个图。。但是第二个图很好理解

技术分享图片

 

技术分享图片

 

 

4. 伪代码

MERGE(A, p, q, r)
    n1 = q-p+1
    n2 = r-q
    //let L[1....n1+1] and R[1....n2+1] be new arrays
    for i =1 to n1
         L[i] = A[p+i-1]
    for j=1 to n2
        R[j] = A[q+j]
    L[n1+1] = ∞
    L[n2+1] = ∞
    i=1
    j=1
    for k =p to r
        if L[i]<=R[j]
            A[k] = L[i]
            i = i + 1
        else
            A[k]=R[j]
            j = j+1

MERGE-SORT(A,p,r)
    if p < r
        q =(p+r)/2  //向下取整,不会打那个符号
        MERGE-SORT(A, p, q)
        MERGE-SORT(A, q+1, r)
        MERGE(A, p, q, r)

 

 5. 算法分析:

  排序就是比较,比较最终都是两个数比较

  直接看MERGE(A, p, q, r)这个算法,这个算法的前提就是假设 A[p] - A[q]是有序的, A[q+1]到A[r]是有序的,那么归并后肯定是有序的.

  怎么做到这个前提,就是最终把所有的数分到最小粒度, 也就是数组只有一个数的时候,它一定是有序的, 然后一层一层向上归并,得到最终的有序序列

6. 代码实现

  java  

void mergeSort(int[] A, int p, int r) {
    if (p < r) {
        int q = (int)Math.floor((p + r)/2);
        mergeSort(A, p, q);
        mergeSort(A, q+1, r);
        merge(A, p, q, r);

    }
}

void merge(int[] A, int p, int q, int r){
    int n1 = q - p + 1;
    int n2 = r - q ;
    int[] L = new int[n1 + 1];
    int[] R = new int[n2 + 1];
    for (int i = 0; i < n1; i++) {
        L[i] = A[p+i];
    }
    for (int j = 0; j < n2; j++) {
        R[j] = A[q+j+1];
    }
    L[n1] = R[n2] = Integer.MAX_VALUE;
    int i = 0, j = 0;

    for (int k = 0; k < r - p + 1; k++) {
        if (L[i] <= R[j]) {
            A[p+k] = L[i];
            i++;
        } else {
            A[p+k] = R[j];
            j++;
        }
    }
}

python

import math
import sys


def merge_sort(arr, p, r):
    if p < r:
        q = math.floor((p + r) / 2)
        merge_sort(arr, p, q)
        merge_sort(arr, q + 1, r)
        merge(arr, p, q, r)


             # 0, 5, 10
def merge(arr, p, q, r):
    n1 = q - p + 1
    n2 = r - q
    m = []
    n = []
    for i in range(n1):
        m.append(arr[p+i])
    for j in range(n2):
        n.append(arr[q+j+1])
    m.append(sys.maxsize)
    n.append(sys.maxsize)
    i = j = 0
    for k in range(r - p + 1):
        if m[i] <= n[j]:
            arr[p+k] = m[i]
            i += 1
        else:
            arr[p+k] = n[j]
            j += 1

c语言

 //                            0,     10
void merge_sort(int arr[], int p, int r)
{
    if(r > p)
    {
        int q = (p + r) / 2;
        merge_sort(arr, p, q);
        merge_sort(arr, q + 1, r);
        merge(arr, p, q, r);
    }
}
 //                        0,     5,     10
void merge(int arr[], int p, int q, int r)
{
    int n1 = q - p +1;
    int n2 = r - q;
    int L[n1+1], R[n2+1];
    int i, j, k;
    for(i = 0; i < n1; i++)    
        L[i] = arr[p+i]; 
    
    for(j = 0; j < n2; j++)
        R[j] = arr[q+j+1];
    L[n1] = R[n2] = (unsigned)(~0) >> 1;
    i = j =0;
    for(k = 0; k < r - p +1; k++)
    {
        if(L[i] <= R[j])
        {
            arr[p+k] = L[i];
            i++;
        }
        else
        {
            arr[p+k] = R[j];
            j++;
        }
    }
}

以上是关于算法导论中,为啥合并排序的递归树的高度为lgn?的主要内容,如果未能解决你的问题,请参考以下文章

算法导论之红黑树的学习

算法导论笔记——第十二~十四章 数据结构树

算法导论归并排序

算法导论第六章堆排序

算法导论归并排序

二叉排序树的最大高度是多少