CLRS 12.4随机构建二叉搜索树

来源:互联网 发布:淘宝搜索页广告位价格 编辑:程序博客网 时间:2024/06/09 14:08

12.4-1
证明前先需要知道有 (44)=(33) 以及附录 C 的练习 C.1-7 需要证明的等式 (nk)=(n1k)+(n1k1)
先证明附录 C 的练习 C.1-7

(n1k)+(n1k1)=(n1)!k!(n1k)!+(n1)!(k1)!(n1k+1)!=(n1k+1)(n1)!k!(n1k+1)!+k(n1)!k!(n1k+1)!=(n1k+1+k)(n1)!k!(n1k+1)!=n!k!(nk)!=(nk)

然后有:
i=0n1(i+33)=(44)+i=1n1(i+33)=(44)+(43)+(53)++(n+23)=(54)+(53)++(n+23)=(n+34)

12.4-2
首先给出第二个问题的答案,即渐进上界 O(nlgn)。证明略,可以参考算法导论指导手册上此题的证明。
下面给出一个例子,n 个结点的平均深度 Θ(lgn) 但高度是 ω(lgn)。其中 nnlgn 个结点是完全二叉树,剩下的是一条单链,高度为:
Θ(lg(nnlgn))+nlgn=Θ(nlgn)=ω(lgn)
这里写图片描述
对此例的平均深度证明是 Θ(lgn) 同样略过。

12.4-3
先给出 n=3 构建出来的全部二叉搜索树。
这里写图片描述
从左到右依次编号为 1,2,3,4,5
1;2;3对应图1;
1;3;2对应图2;
2;1;32;3;1 对应图3;
3;2;1对应图4;
3;1;2对应图5。
因此图3被创建的概率是 2/6,其余的是 1/6。而随机构建二叉搜索树都是 1/5

12.4-4
在书的附录里面有凸函数的定义(见中文版第三版的P701或英文版的P1199),然后国外的语意和国内相反,所以我们是要证明 f(x)=2x 是凹函数。
证明:根据凹函数定义:对于任意 x,y,λ(0,1),有 λ2x+(1λ)2y2(λx+(1λ)y)……①
这里有个重要不等式,即对于任意 a,b,c都有 cacb+(ab)(cb)lnc。在这简单证明一下,根据 ex1+x有:设 x=(ab)lnc 带入 e((ab)lnc)1+(ab)lncc(ab)1+(ab)lnc 两边都乘以 cb 即得证。
这样用 2 代替 c,x 代替 a,z 代替 b,其中 z=λx+(1λ)y
带入并化解得:2x2z+(xz)(2z)….②同理,ay 其他一样,得 2y2z+(yz)(2z)….③。
把②和③式带入①式得:

λ2x+(1λ)2yλ(2z+(xz)(2z))+(1λ)(2z+(yz)(2z))=(λ+1λ)2z+(λ(xz)+(1λ)(yz))(2z)

由于 (λ(xz)+(1λ)(yz))=0,所以 λ2x+(1λ)2y2z=2(λx+(1λ)y),得证!

12.4-5
略。



附上本章的一些实现代码

#include <iostream>#include <stack>using std::cout;using std::endl;using std::stack;struct BinTree{    int key;    BinTree *parent;    BinTree *left;    BinTree *right;};void preOrder(BinTree *root){    if(root != NULL)    {        cout << root->key << ' ';        preOrder(root->left);        preOrder(root->right);    }}void non_recursive_preOrder(BinTree *root){    stack<BinTree *> ptr;    ptr.push(root);    while(root != NULL && !ptr.empty())    {        BinTree *p = ptr.top();        cout << p->key << ' ';        ptr.pop();        if(p->right != NULL)            ptr.push(p->right);        if(p->left != NULL)            ptr.push(p->left);    }}void inOrder(BinTree *root){    if(root != NULL)    {        inOrder(root->left);        cout << root->key << ' ';        inOrder(root->right);    }}void non_recursive_inOrder(BinTree *root){    stack<BinTree *> ptr;    BinTree *p = root;    while(p != NULL || !ptr.empty())    {        while(p != NULL)    //找到最左孩子        {            ptr.push(p);            p = p->left;        }        if(!ptr.empty())    //弹出,然后向右        {            p = ptr.top();            ptr.pop();            cout << p->key << ' ';            p = p->right;        }    }}void postOrder(BinTree *root){    if(root != NULL)    {        postOrder(root->left);        postOrder(root->right);        cout << root->key << ' ';    }}void non_recursive_postOrder(BinTree *root){    stack<BinTree *> ptr;    BinTree *cur;    BinTree *pre = NULL;    ptr.push(root);    while(!ptr.empty())    {        cur = ptr.top();        //当前结点没孩子或者左(右)孩子已经访问过,则访问当前结点        if(cur->left == NULL && cur->right == NULL || pre != NULL && (pre == cur->left || pre == cur->right))        {            cout << cur->key << ' ';            ptr.pop();            pre = cur;        }        else        {            if(cur->right != NULL)                ptr.push(cur->right);            if(cur->left != NULL)                ptr.push(cur->left);        }    }}BinTree *TREE_SEARCH(BinTree *root,int value){    if(root == NULL)        return root;    if(root->key == value)        return root;    if(root->key < value)        TREE_SEARCH(root->right,value);    else TREE_SEARCH(root->left,value);}BinTree *non_recursive_TREE_SEARCH(BinTree *root,int value){    while(root != NULL && root->key != value)    {        if(root->key < value)            root = root->right;        else root = root->left;    }    return root;}BinTree *TREE_MINIMUM(BinTree *root){    if(root == NULL)        return root;    if(root->left == NULL)        return root;    else return TREE_MINIMUM(root->left);}BinTree *non_recursive_TREE_MINIMUM(BinTree *root){    if(root == NULL)        return root;    while(root->left != NULL)        root = root->left;    return root;}BinTree *TREE_MAXIMUM(BinTree *root){    if(root == NULL)        return root;    if(root->right == NULL)        return root;    else return TREE_MAXIMUM(root->right);}BinTree *non_recursive_TREE_MAXIMUM(BinTree *root){    if(root == NULL)        return root;    while(root->right != NULL)        root = root->right;    return root;}BinTree *TREE_SUCCESSOR(BinTree *p){    if(p == NULL)        return p;    if(p->right != NULL)        return TREE_MINIMUM(p->right);    BinTree *x = p->parent;    while(x != NULL && p == x->right)    {        p = x;        x = x->parent;    }    return x;}BinTree *TREE_PREDECESSOR(BinTree *p){    if(p == NULL)        return p;    if(p->left != NULL)        return TREE_MAXIMUM(p->left);    BinTree *x = p->parent;    while(x != NULL && p == x->left)    {        p = x;        x = x->parent;    }    return x;}void TREE_INSERT(BinTree **root,int key){    if(*root == NULL)   //插入根节点    {        BinTree *z = new BinTree;        z->key = key;        z->left = z->right = NULL;        *root = z;        z->parent = NULL;        return;    }    BinTree *x = *root;    if(x->key > key)    //左子树    {        if(x->left == NULL) //左子树为空        {            BinTree *z = new BinTree;            z->key = key;            z->left = z->right = NULL;            z->parent = x;            x->left = z;        }        else TREE_INSERT(&(x->left),key);//以左子树为根递归插入    }    else        //右子树    {        if(x->right == NULL)        {            BinTree *z = new BinTree;            z->key = key;            z->left = z->right = NULL;            z->parent = x;            x->right = z;        }        else TREE_INSERT(&(x->right),key);    }}void non_recursive_TREE_INSERT(BinTree **root,int key){    BinTree *z = new BinTree;    z->key = key;    z->left = z->right = NULL;    BinTree *y = NULL;    BinTree *x = *root;    while(x != NULL)    {        y = x;        if(x->key < z->key)            x = x->right;        else x = x->left;    }    z->parent = y;    if(y == NULL)        *root = z;    else if(y->key < z->key)        y->right = z;    else y->left = z;}void TRANSPLANT(BinTree **root,BinTree *u,BinTree *v){    if(u->parent == NULL)        *root = v;    else if(u == u->parent->left)        u->parent->left = v;    else u->parent->right = v;    if(v != NULL)        v->parent = u->parent;}void TREE_DELETE(BinTree **root,int key){    BinTree *p = TREE_SEARCH(*root,key);    if(p == NULL)        return;    if(p->left == NULL)        TRANSPLANT(root,p,p->right);    else if(p->right == NULL)        TRANSPLANT(root,p,p->left);    else{        BinTree *y = TREE_MINIMUM(p->right);        if(y->parent != p)        {            TRANSPLANT(root,y,y->right);            y->right = p->right;            y->right->parent = y;        }        TRANSPLANT(root,p,y);        y->left = p->left;        y->left->parent = y;    }    delete p;}int main(){    BinTree *root = NULL;    int array[] = {8,2,-5,1,77,-6,45,0,5};    for(int i = 0; i < 5; ++i)        TREE_INSERT(&root,array[i]);    //创建树    for(int i = 5; i < 9; ++i)        non_recursive_TREE_INSERT(&root,array[i]);  //接上继续创建,在这只是为了测试    //分别用先中后序输出,包括每种顺序的递归和非递归    cout << "preOrder: ";    preOrder(root);    cout << endl;    cout << "non recursive preOrder: " ;    non_recursive_preOrder(root);    cout << endl;    cout << "inOrder: " ;    inOrder(root);    cout << endl;    cout << "non recursive inOrder: ";    non_recursive_inOrder(root);    cout << endl;    cout << "postOrder: ";    postOrder(root);    cout << endl;    cout << "non recursive postOrder: ";    non_recursive_postOrder(root);    cout << endl;    //查找元素,找到则输出并找到该元素的前驱和后继    BinTree *p = TREE_SEARCH(root,77);    if(p != NULL){        cout << "find " << p->key << endl;        cout << "it's predecessor and successor: ";        BinTree *pre = TREE_PREDECESSOR(p);        if(pre != NULL)            cout << pre->key << ' ';        else cout << "NULL" << ' ';        BinTree *succ = TREE_SUCCESSOR(p);        if(succ != NULL)            cout << succ->key << ' ';        else cout << "NULL" << ' ';        cout << endl;    }    else cout << "can not find in the tree" << endl;    p = TREE_SEARCH(root,66);    if(p != NULL){        cout << "find " << p->key << endl;        cout << "it's predecessor and successor: ";        BinTree *pre = TREE_PREDECESSOR(p);        if(pre != NULL)            cout << pre->key << ' ';        else cout << "NULL" << ' ';        BinTree *succ = TREE_SUCCESSOR(p);        if(succ != NULL)            cout << succ->key << ' ';        else cout << "NULL" << ' ';        cout << endl;    }    else cout << "can not find in the tree" << endl;    p = TREE_SEARCH(root,8);    if(p != NULL){        cout << "find " << p->key << endl;        cout << "it's predecessor and successor: ";        BinTree *pre = TREE_PREDECESSOR(p);        if(pre != NULL)            cout << pre->key << ' ';        else cout << "NULL" << ' ';        BinTree *succ = TREE_SUCCESSOR(p);        if(succ != NULL)            cout << succ->key << ' ';        else cout << "NULL" << ' ';        cout << endl;    }    else cout << "can not find in the tree" << endl;    //找到树的最小和最大值    p = TREE_MINIMUM(root);    if(p != NULL)        cout << "minimum is: " << p->key << endl;    p = TREE_MAXIMUM(root);    if(p != NULL)        cout << "maximum is: " << p->key << endl;    //删除操作    TREE_DELETE(&root,8);    p = TREE_SEARCH(root,8);    if(p != NULL){        cout << "find " << p->key << endl;        cout << "it's predecessor and successor: ";        BinTree *pre = TREE_PREDECESSOR(p);        if(pre != NULL)            cout << pre->key << ' ';        else cout << "NULL" << ' ';        BinTree *succ = TREE_SUCCESSOR(p);        if(succ != NULL)            cout << succ->key << ' ';        else cout << "NULL" << ' ';        cout << endl;    }    else cout << "can not find in the tree" << endl;    //删除后中序遍历    inOrder(root);    cout << endl;    return 0;}
0 0
原创粉丝点击