您的位置:首页 > 其它

二叉树知识点

2016-02-18 17:43 253 查看
高度为h的平衡二叉树

最少包含的节点个数为:

f(1) = 1,f(2)=2,f(3)=4,f(4)=7............f(n+2) = f(n+1)+f(n)+1.

最少包含的叶节点个数为:

f(1)=1,f(2)=1,f(3)=2,f(4)=3,f(5)=5,f(6)=8.......f(n+2)=f(n+1)+f(n).//斐波那契数列。

#include <iostream>

#include <queue>

#include <stack>

#include <list>

using namespace std;

class binaryTreeNode{

public:

    int el;

    binaryTreeNode * left;

    binaryTreeNode * right;

    binaryTreeNode(){

        left = right = 0;

    }

    binaryTreeNode(const int e,binaryTreeNode*l=0,binaryTreeNode*r=0){

        el=e;

        left = l;

        right = r;

    }

};

class binaryTree{

public:

    binaryTree(){

        root = 0;

    }

    binaryTree(binaryTreeNode*r){

        root = r;

    }

    bool isEmpty()const{

        return root==0;

    }

    int GetNum(){//求二叉树的节点个数

        return GetNum(root);

    }

    int deep(){//求二叉树的深度

        return deep(root);

    }

    //递归深度优先遍历

    void prorder(){

        prorder(root);

    }

    void inorder(){

        inorder(root);

    }

    void postorder(){

        postorder(root);

    }

    //用队列实现广度优先遍历

    void levelTravel(){

        levelTravel(root);

    }

    //求二叉树第k层的节点个数

    int getNumKLevel(int k){

        getNumKLevel(root,k);

    }

    //求二叉树中叶节点的个数

    int leafNum(){

        return leafNum(root);

    }

    //判断两棵二叉树是否结构相同

    bool strcmp(binaryTree&t){

        return strcmp(root,t.root);

    }

    //判断二叉树是否为平衡二叉树

    bool isAVL(){

        return isAVL(root);

    }

    //求二叉树的镜像

    binaryTree Mirror(){

        return binaryTree(Mirror(root));

    }

    //求二叉树种两个节点的最低公共祖先

    binaryTreeNode* getLastCommonParent(binaryTreeNode*p1,binaryTreeNode*p2){

        return getLastCommonParent(root,p1,p2);

    }

    //非递归的深度优先遍历

    void iterproder();

    void iterinorder();

    void iterpostorder();

    //判断二叉树是否是完全二叉树

    bool isComplate(){

        return isComplate(root);

    }

    //判断是否是二叉排序树

    bool isBinarySort(){

        return isBinarySort(root);

    }

protected:

    binaryTreeNode * root;

    int GetNum(binaryTreeNode*);//二叉树的节点个数

    int deep(binaryTreeNode*);//二叉树的深度

    virtual void visit(binaryTreeNode*p){

        cout<<p->el<<" ";

    }

    //递归深度优先遍历

    void prorder(binaryTreeNode*);

    void inorder(binaryTreeNode*);

    void postorder(binaryTreeNode*);

    //广度优先遍历

    void levelTravel(binaryTreeNode*);

    //求二叉树第K层的节点个数

    getNumKLevel(binaryTreeNode*,int);

    //求二叉树中叶节点的个数

    int leafNum(binaryTreeNode*);

    //判断两棵二叉树是否相同

    bool strcmp(binaryTreeNode*,binaryTreeNode*);

    //判断二叉树是否为平衡二叉树

    bool isAVL(binaryTreeNode*);

    //求二叉树的镜像

    binaryTreeNode* Mirror(binaryTreeNode*);

    //求二叉树种两个节点的最低公共祖先

    bool foundNode(binaryTreeNode*,binaryTreeNode*);

    binaryTreeNode* getLastCommonParent(binaryTreeNode*,binaryTreeNode*,binaryTreeNode*);

    bool getNodePath(binaryTreeNode*,binaryTreeNode*,list<binaryTreeNode*>&);

    binaryTreeNode* getLastCommonParent2(binaryTreeNode*,binaryTreeNode*,binaryTreeNode*);

    //判断是否是完全二叉树

    bool isComplate(binaryTreeNode*);

    //判断是否是二叉排序树

    bool isBinarySort(binaryTreeNode*);

};

//二叉树的节点个数

int binaryTree::GetNum(binaryTreeNode*p){

    if(p==0)

        return 0;

    else

        return 1+GetNum(p->left)+GetNum(p->right);

}

//二叉树的深度

int binaryTree::deep(binaryTreeNode*p){

    if(p==0)

        return 0;

    else

        return 1+(deep(p->left)>deep(p->right))?deep(p->left):deep(p->right);

}

//3种递归深度优先遍历

void binaryTree::prorder(binaryTreeNode*p){

    if(p!=0)

    {

    visit(p);

    prorder(p->left);

    prorder(p->right);

    }

}

void binaryTree::inorder(binaryTreeNode*p){

    if(p!=0){

        inorder(p->left);

        visit(p);

        inorder(p->right);

    }

}

void binaryTree::postorder(binaryTreeNode*p){

    if(p!=0){

        postorder(p->left);

        postorder(p->right);

        visit(p);

    }

}

//用队列实现广度优先遍历

void binaryTree::levelTravel(binaryTreeNode*p){

    queue<binaryTreeNode*> q;

    binaryTreeNode * t;

    if(p!=0)

    {

        q.push(p);

        while(!q.empty()){

            t = q.front();

            visit(t);

            q.pop();

            if(t->left);

            q.push(t->left);

            if(t->right)

            q.push(t->right);

        }

    }

}

//求二叉树第K层的节点个数

int binaryTree::getNumKLevel(binaryTreeNode*p,int k){

    if(p==0||k<1)

        return 0;

    else if(k==1)

        return 1;

    return (getNumKLevel(p->left,k-1)+getNumKLevel(p->right,k-1));

}

//求二叉树中叶节点的个数

int binaryTree::leafNum(binaryTreeNode*p){

    if(p==0)

        return 0;

    else if(p->left==0&&p->right==0)

        return 1;

    else

        return (leafNum(p->right)+leafNum(p->left));

}

//判断两棵二叉树是否相同

bool binaryTree::strcmp(binaryTreeNode*p1,binaryTreeNode*p2){

    if(p1==0&&p2==0)

        return true;

    else if(p1==0||p2==0)

        return false;

    else

        return strcmp(p1->left,p2->left)&&(p1->ri
4000
ght,p2->right);

}

//判断是否为平衡二叉树

bool binaryTree::isAVL(binaryTreeNode*p){

    if(p==0)

        return true;

    int left = deep(p->left);

    int right = deep(p->right);

    int diff = right - left;

    if(diff <=-1 || diff >= 1)

        return false;

    return(isAVL(p->left)&&isAVL(p->right));

}

//求二叉树的镜像

binaryTreeNode* binaryTree::Mirror(binaryTreeNode*p){

    binaryTreeNode * p1;

    if(p==0)

        return 0;

    binaryTreeNode * pl = Mirror(p->left);

    binaryTreeNode * pr = Mirror(p->right);

    p1->left = pr;

    p1->right = pl;

    return p1;

}

//求二叉树种两个节点的最低公共祖先

bool binaryTree::foundNode(binaryTreeNode*p1,binaryTreeNode*p2){

    if(p1==0||p2==0)

        return false;

    if(p1==p2)

        return true;

    bool found = foundNode(p1->left,p2);

    if(!found)

    found = foundNode(p1->right,p2);

    return found;

}

//递归解法:

//如果两个节点分别在根节点的左子树和右子树,则返回根节点

//如果两个节点都在左子树,则递归处理左子树;如果两个节点都在右子树,则递归处理右子树

binaryTreeNode* binaryTree::getLastCommonParent(binaryTreeNode*r,binaryTreeNode*p1,binaryTreeNode*p2){

    if(foundNode(r->left,p1)){

        if(foundNode(r->right,p2))

            return r;

        else

            return getLastCommonParent(r->left,p1,p2);

    }

    else{

        if(foundNode(r->left,p2))

            return r;

        else

            return getLastCommonParent(r->right,p1,p2);

    }

}

//非递归解法:

//先求从根节点到两个节点的路径,然后再比较对应路径的节点就行,最后一个相同的节点也就是他们在二叉树中的最低公共祖先节点

bool binaryTree::getNodePath(binaryTreeNode*r,binaryTreeNode*p,list<binaryTreeNode*>&path){

    if(r==p){

        path.push_back(r);

        return true;

    }

    if(r==0)

        return false;

    path.push_back(r);

    bool found = false;

    found = getNodePath(r->left,p,path);

    if(!found)

    found = getNodePath(r->right,p,path);

    if(!found)

        path.pop_back();

    return found;

}

binaryTreeNode*binaryTree::getLastCommonParent2(binaryTreeNode*r,binaryTreeNode*p1,binaryTreeNode*p2){

    if(r==0||p1==0||p2==0)

        return nullptr;

    list<binaryTreeNode*>path1;

    bool bresult1 = getNodePath(r,p1,path1);

    list<binaryTreeNode*>path2;

    bool bresult2 = getNodePath(r,p2,path2);

    if(!bresult1||!bresult2)

        return nullptr;

    binaryTreeNode * pLast = NULL;

    list<binaryTreeNode*>::const_iterator iter1 = path1.begin();

    list<binaryTreeNode*>::const_iterator iter2 = path2.begin();

    while(iter1!=path1.end()&&iter2!=path2.end()){

        if(*iter1 == *iter2)

            pLast = *iter1;

        iter1++;

        iter2++;

    }

    return pLast;

}

//非递归先序遍历

void binaryTree::iterproder(){

    stack<binaryTreeNode*> s;

    binaryTreeNode*p = root;

    if(p!=0){

        s.push(p);

    while(!s.empty()){

        p = s.top();

        s.pop();

        visit(p);

        if(p->right!=0)

            s.push(p->right);

        if(p->left!=0)

            s.push(p->left);

    }

    }

}

//非递归中序遍历

//若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理

//若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子

void binaryTree::iterinorder(){

    binaryTreeNode * p =root;

    stack<binaryTreeNode*>s;

    while(p!=0||!s.empty()){

        while(p!=0){

            s.push(p);

            p=p->left;

        }

        if(!s.empty()){

            p=s.top();

            visit(p);

            s.pop();

            p=p->right;

        }

    }

}

//非递归后序遍历

/*对于任一结点P,将其入栈,然后沿其左子树一直往下搜索,直到搜索到没有左孩子的结点,此时该结点出现在栈顶,

但是此时不能将其出栈并访问,因此其右孩子还为被访问。所以接下来按照相同的规则对其右子树进行相同的处理,

当访问完其右孩子时,该结点又出现在栈顶,此时可以将其出栈并访问。

这样就保证了正确的访问顺序。可以看出,在这个过程中,每个结点都两次出现在栈顶,只有在第二次出现在栈顶时,才能访问它。

因此需要多设置一个变量标识该结点是否是第一次出现在栈顶。

*/

void binaryTree::iterpostorder(){

    stack<binaryTreeNode*>s;

    binaryTreeNode*p = root,*q=root;

    while(p!=0){

        for(;p->left!=0;p=p->left)

            s.push(p);

        while(p->right==0||p->right==q){

            visit(p);

            q=p;

            if(s.empty())

                return;

            p=s.top();

            s.pop();

        }

        s.push(p);

        p=p->right;

    }

}

//判断是否是完全二叉树

bool binaryTree::isComplate(binaryTreeNode*p){

    queue<binaryTreeNode*>q;

    if(p==0)

        return true;

    int tag = 0;

    q.push(p);

    while(!q.empty()){

        p = q.front();

        q.pop();

        if(p->left&&!tag)

            q.push(p->left);

        else if(p->left)

            return false;

        else

            tag =1;

        if(p->right&&!tag)

            q.push(p->right);

        else if(p->right)

            return false;

        else

            tag =1;

    }

    return true;

}

//判断是否是二叉查找树

bool binaryTree::isBinarySort(binaryTreeNode*p){

    binaryTreeNode* pre = 0;

    stack<binaryTreeNode*> s;

    while(p!=0||!s.empty()){

        if(p){

            s.push(p);

            p=p->left;

        }

        else{

            p = s.top();

            s.pop();

            if(pre&&(pre->el>=p->el))

                return false;

            pre = p;

            p=p->right;

        }

    }

    return true;

}

int main()

{

    cout << "Hello world!" << endl;

    return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: