ch4.7: given 2 huge Binary tree t1, t2(>1millon nodes), decide if one tree is subtree of another one

本文介绍了一种高效的算法来判断一棵较小的二叉树是否为另一棵较大二叉树的子树。通过递归匹配的方法实现,适用于大规模数据集的场景。文章提供了完整的代码实现,并展示了具体的例子验证算法的有效性。
// Ch4.7: You have two very large binary trees: T1, with millions of nodes, and T2, 
// with hundreds of nodes. Create an algorithm to decide if T2 is a subtree of T1

#include 
#include 
#include 
#include 
using namespace std;

class BinNode{
public:
    int key;
    BinNode *parent, *lChild, *rChild;
    BinNode(){}
    BinNode(int t): key(t), parent(NULL), lChild(NULL), rChild(NULL){}
};

class BTree{
private:
    BinNode *m_root;
public:
    BTree(): m_root(NULL){}
    BTree(BinNode *t): m_root(t){}

    BinNode* getRoot() const{return m_root;}
    
    BinNode* balanceTree(BinNode* pnode, BinNode *parent, int *arr, int low, int high){
        if(low>high || arr == NULL)
            return NULL;
        int mid = (low+high)>>1;
        pnode = new BinNode(arr[mid]);
        pnode->parent = parent;
        pnode->lChild = balanceTree(pnode->lChild, pnode, arr, low, mid-1);
        pnode->rChild = balanceTree(pnode->rChild, pnode, arr, mid+1, high);

        return pnode;
    }

    void PrintPre(BinNode *pnode)
    {
        if(pnode == NULL)
            return;
 
        cout << pnode->key << " ";
        PrintPre(pnode->lChild);
        PrintPre(pnode->rChild);        
    }

    BinNode* minimal(BinNode* pnode){
        if(pnode==NULL) return NULL;
        while(pnode->lChild){
            pnode = pnode->lChild;
        }
        return pnode;
    }

    BinNode* successor(BinNode* qnode){
        if(qnode==NULL) return NULL;
        if(qnode->rChild) return minimal(qnode->rChild);
        BinNode *r = qnode->parent;
        while(r && r->rChild==qnode){
            qnode = r;
            r = r->parent;
        }
        return r;
    }

///////////////////////////////////////////////////////////////////////////
/*
    use divide and conqur with 2 helper methods, also, only go down of r1,
    r2 is stable.
    be carefull in determining the corner cases!
*/
    bool match(BinNode *r1, BinNode *r2){
        if(r1==NULL && r2==NULL) return true;  // LOOKOUT
        else if(r1==NULL || r2==NULL) return false;
        else if(r1->key!=r2->key) return false;
        else return match(r1->lChild, r2->lChild) && match(r1->rChild, r2->rChild);
    }

    bool subtree(BinNode *r1, BinNode *r2){
        if(r1==NULL) return false;              // LOOKOUT
        else if(r1->key==r2->key){
            return match(r1, r2);
        }
        else return subtree(r1->lChild, r2) || subtree(r1->rChild, r2);
    }

    bool contain_tree(BinNode *r1, BinNode *r2){
        if(r2 == NULL) return false;            // LOOKOUT
        else return subtree(r1, r2);
    }


// Auxilary methods:
    BinNode* searchND(BinNode* x_head, int x){
        if(x_head==NULL) return NULL;
        else if(x==x_head->key) return x_head;
        else if(x<=x_head->key) searchND(x_head->lChild, x);
        else searchND(x_head->rChild, x);
    }

    vector> BFSlist(BinNode *head){
        vector> res;
        int level = 0;
        list li;
        li.push_back(head);
        res.push_back(li);
        while(!res[level].empty()){
            list l;
            list::iterator it;
            for(it=res[level].begin(); it!=res[level].end(); ++it){
                BinNode *n = *it;
                if(n->lChild) l.push_back(n->lChild);
                if(n->rChild) l.push_back(n->rChild);
            }
            ++level;
            res.push_back(l);
        }
        return res;
    }

    void print(vector > res){
        vector >::iterator vit;
        for(vit=res.begin(); vit!=res.end(); ++vit){
            list li = *vit;
            list::iterator lit;
            for(lit=li.begin(); lit!=li.end(); ++lit){
                BinNode *n = *lit;
                cout<key<<" ";
            }
            cout<balanceTree(bt1->getRoot(), NULL, a1, 0, 6);
    bt1 = new BTree(proot1);
    bt1->PrintPre(bt1->getRoot());
    cout <<"\na2:\n";
    // BTree from a2[]
    BTree *bt2 = new BTree();
    BinNode *proot2 = bt2->balanceTree(bt2->getRoot(), NULL, a2, 0, 2);
    bt2 = new BTree(proot2);
    bt2->PrintPre(bt2->getRoot());
    
    cout << "\nD-dimesion linked list showoff-------\n";
    vector> jerry1 = bt1->BFSlist(proot1);
    bt1->print(jerry1);

    cout << "\nD-dimesion linked list showoff-------\n";
    vector> jerry2 = bt2->BFSlist(proot2);
    bt2->print(jerry2);

    //
    if (bt1->contain_tree(proot1, proot2))  // contain_tree belong to bt1/2
        cout<<"tree r1 contains r2"<


implement the preetydraw snippets from leetcode for demonstration.
Executing the program....
$demo 
Balanced tree in array format
a1:
0----------6
3 1 0 2 5 4 6 Tree pretty print with level=1 and indentSpace=0


    ___3__
   /      \
  _1      _5
 /  \    /  \
 0   2   4   6
a2:
0----------2
1 0 2 Tree pretty print with level=1 and indentSpace=0


  _1
 /  \
 0   2

So we can easily verify that a2 is a subtree of a1.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值