面试经典二叉树算法

#include <iostream>
#include <cstdlib>
#include <cassert>
#include <stack>
#include <cmath>
#include <queue>
#include <list>
using namespace std;

//面试经典二叉树算法
typedef char ElemType;
#define END '#'
template <typename T>
const T & Max(const T& a,const T & b)
{
    return a>b?a:b;
}

typedef struct BtNode
{
    //BtNode *parent;
    BtNode *leftchild;
    BtNode *rigthchild;
    ElemType data;
}BtNode , *BinaryTree;
BtNode * _Buynode()
{
    BtNode *s = (BtNode *)malloc(sizeof(BtNode));
    if(NULL == s) exit(1);
    memset(s,0,sizeof(BtNode));
    return s;
}
void _Freenode(BtNode *p)
{
    free(p);
}
//利用出栈的顺序进行遍历
struct StkNode
{
    BtNode * Btnode;
    int PopNum;
public:
    StkNode(BtNode * ptr = NULL)
        :Btnode(ptr),PopNum(0)
    {}
};
//中序
void IsTree_struct_pop_num(BtNode *ptr)
{
    if(ptr == NULL)
    {
        return ;
    }
    stack<StkNode> st;
    st.push(StkNode(ptr));
    while (!st.empty())
    {
        StkNode p = st.top();
        st.pop();
        p.PopNum++;
        if( p.PopNum == 2 )
        {
            cout<<p.Btnode->data<< " ";
            if( p.Btnode->rigthchild != NULL )
            {
                st.push(StkNode(p.Btnode->rigthchild));
            }
        } else {
            st.push(StkNode(p));
            if(p.Btnode->leftchild != NULL) {
                st.push(StkNode(p.Btnode->leftchild));
            }
        }
    }
}

//后序
void PassTree_struct_pop_num(BtNode *ptr)
{
    if(ptr == NULL)
    {
        return ;
    }
    stack<StkNode> st;
    st.push(StkNode(ptr));
    while (!st.empty())
    {
        StkNode pt = st.top();
        st.pop();
        pt.PopNum++;
        if(pt.PopNum == 3) //第三次出栈,打印
        {
            cout<<pt.Btnode->data<<" ";
        }
        else
        {
            st.push(ptr);
            if(pt.PopNum == 1 && pt.Btnode->leftchild != NULL)
            {
                st.push(StkNode(pt.Btnode->leftchild));
            }
            else if(pt.PopNum == 2 && pt.Btnode->rigthchild != NULL)
            {
                st.push(StkNode(pt.Btnode->rigthchild));
            }
        }
    }
}
//创建二叉树
BtNode* Create_Tree(const char * &str)
{
    BtNode * s = NULL;
    if(str == NULL)
    {
        return NULL;
    }
    if(*str != END)
    {
        s = _Buynode();
        s->data = *str;
        s->leftchild = Create_Tree(++str);
        s->rigthchild = Create_Tree(++str);
    }

    return s;
}
//前序递归
void PreTree(BtNode *ptr)
{
    if(ptr == NULL)
    {
        return ;
    }
    else
    {
        cout<<ptr->data<<" ";
        PreTree(ptr->leftchild);
        PreTree(ptr->rigthchild);
    }

}

//前序非递归
void PreOrder2(BtNode *ptr)
{
    if(ptr == NULL)
    {
        return;
    }
    stack<BtNode *>st;
    st.push(ptr);
    while (!st.empty())
    {
        ptr = st.top();
        st.pop();
        cout <<ptr->data<<" ";
        if(ptr->rigthchild != NULL) //right
        {
            st.push(ptr->rigthchild);
        }
        if(ptr->leftchild  != NULL)//left
        {
            st.push(ptr->leftchild);
        }       
    }
}
//前序非递归
void PreOrder1(BtNode *ptr)
{
    if(ptr == NULL)
    {
        return;
    }
    stack<BtNode*> st;

    while (ptr != NULL || !st.empty())
    {
        while (ptr != NULL)
        {
            cout<<ptr->data<<" ";
            st.push(ptr);
            ptr = ptr->leftchild;
        }
        ptr = st.top();
        st.pop();
        ptr = ptr->rigthchild;
    }
}
//中序非递归
void IsOrder(BtNode * ptr)
{
    if(ptr == NULL)
    {
        return;
    }
    stack<BtNode *> st;
    while(ptr != NULL || !st.empty())
    {
        while(ptr != NULL)
        {
            st.push(ptr);
            ptr = ptr->leftchild;
        }
        ptr = st.top();
        st.pop();
        cout<<ptr->data<<" ";

        ptr = ptr->rigthchild;
    }
}
//后续非递归
void PassOrder(BtNode *ptr)
{
    if(ptr == NULL)
    {
        return;
    }
    stack<BtNode*> st;
    BtNode *flag = NULL;

    while (ptr != NULL || !st.empty())
    {
        while (ptr != NULL)
        {
            st.push(ptr);
            ptr = ptr->leftchild;
        }
        ptr = st.top();
        st.pop();
        if(ptr->rigthchild == NULL || flag == ptr->rigthchild)
        {
            cout<<ptr->data<<" ";
            flag = ptr;
            ptr  = NULL; //如果已经访问了的数据节点,则此节点将会失去生命周期,没有意义
        }
        else
        {
            st.push(ptr); //他的右子树还没有访问
            ptr = ptr->rigthchild;
        }
    }

    cout<<endl;
}
//树高
int Hight_Tree(BtNode *ptr)
{
    if(ptr == NULL)
    {
        return 0;
    }
    if(ptr->leftchild == NULL && ptr->rigthchild == NULL)
    {
        return 1;
    }
    int lefthight  = Hight_Tree(ptr->leftchild);
    int righthight = Hight_Tree(ptr->rigthchild);

    return Max(lefthight,righthight)+1;
}
//节点个数
int Size_Tree(BtNode *ptr)
{
    if(ptr == NULL)
    {
        return 0;
    }
    return Size_Tree(ptr->leftchild)+Size_Tree(ptr->rigthchild)+1;
}
//叶节点个数
int leave_Tree(BtNode *ptr)
{
    if(ptr == NULL)
    {
        return 0;
    }
    if(ptr->leftchild == NULL && ptr->rigthchild == NULL)
    {
        return 1;
    }
    return leave_Tree(ptr->rigthchild)+leave_Tree(ptr->leftchild)+1;
}
//完全二叉树
bool Is_Comp_Binary_Tree(BtNode *ptr)
{
    if(ptr == NULL)
    {
        return true;
    }
    queue<BtNode *> qu;
    qu.push(ptr);
    bool result = true;
    bool flag = false;
    while (!qu.empty())
    {
        ptr = qu.front();
        qu.pop();
        if(flag)
        {
            if(ptr->leftchild != NULL || ptr->rigthchild !=NULL)
            {
                result = false;
                break;
            }
        }
        if(ptr->leftchild != NULL && ptr->rigthchild == NULL)
        {
            qu.push(ptr->leftchild);
            flag = true;
        }
        if(ptr->leftchild == NULL && ptr->rigthchild == NULL)
        {
            flag = true;
        }
        if(ptr->leftchild == NULL && ptr->rigthchild != NULL)
        {
            result = false;
            break;
        }
        if(ptr->leftchild != NULL && ptr->rigthchild !=NULL)
        {
            qu.push(ptr->leftchild);
            qu.push(ptr->rigthchild);
        }
    }

    return result;
}
//满二叉树
bool Is_Full_Binary_Tree(BtNode *ptr)
{
    if(ptr == NULL)
    {
        return true;
    }
    int higth = Hight_Tree(ptr);
    int sizecount  = Size_Tree(ptr);
    int leave = leave_Tree(ptr);
    if((sizecount ==  pow(2,higth)-1) && leave == pow(2,higth-1))
    {
        return true;
    }
    else
    {
        return false;
    }   
}
//树节点
int GetNumTree(BtNode *ptr)
{
    if(ptr == NULL)
    {
        return 0;
    }

    return GetNumTree(ptr->leftchild)+GetNumTree(ptr->rigthchild)+1;
}

//打印倒数第k个
void PrintCompBTree(BtNode *ptr, int k)//倒数第k个节点
{
    assert(ptr != NULL);
    int len = GetNumTree(ptr);
    if(ptr == NULL ||k < 0 || k > len)
    {
        return;
    }
    int k1 = len-k;
    int i = 0;
    queue<BtNode*> queue;
    queue.push(ptr);
    while (!queue.empty())
    {
        ptr = queue.front();
        queue.pop();
        i++;
        if( i == k1)
        {
            cout<<"倒数第"<<k<<"个节点:"<<ptr->data<<endl;
            break;
        }
        if(ptr->leftchild != NULL)
        {
            queue.push(ptr->leftchild);
        }
        if(ptr->rigthchild != NULL)
        {
            queue.push(ptr->rigthchild);
        }
    }
}
int GetBinaryTreeLevel(BtNode *ptr, int k)
{
    if(ptr == NULL || k < 0)
    {
        return 0;
    }
    if(k == 1)
    {
        return 1;
    }
    int leftcount  = GetBinaryTreeLevel(ptr->leftchild,k-1);
    int rightcount = GetBinaryTreeLevel(ptr->rigthchild,k-1);

    return  leftcount+rightcount;
}

//平衡二叉树
bool IsBalance_BinaryTree(BtNode *ptr,int &hight)
{
    if(ptr == NULL)
    {
        hight = 0;
        return false;
    }
    if(ptr->leftchild == NULL && ptr->rigthchild != NULL)
    {
        return false;
    }
    if(ptr->rigthchild != NULL && ptr->leftchild == NULL)
    {
        return false;
    }
    int lefthight  = 0;
    int righthight = 0;
    bool boolleft  = IsBalance_BinaryTree(ptr->leftchild,lefthight);
    bool boolright = IsBalance_BinaryTree(ptr->rigthchild,righthight);

    return boolright && boolleft && (abs(lefthight - righthight) <=1);
}
//查找节点
bool FindNode_Tree(BtNode *ptr,BtNode *child)
{
    if(ptr == NULL || child == NULL)
    {
        return false;
    }
    if(ptr == child)
    {
        return true;
    }
    bool flag = FindNode_Tree(ptr->leftchild ,child);
    if(!flag)
    {
        flag = FindNode_Tree(ptr->rigthchild,child);
    }

    return flag;
}
//寻找相同祖父
BtNode * FindComParent(BtNode *ptr, BtNode *child1,BtNode *child2)
{
    if(ptr == NULL || child1 == NULL || child2 == NULL)
    {
        return NULL;
    }
    if(FindNode_Tree(ptr->leftchild,child1))   // 左右 ---- 
    {
        if(FindNode_Tree(ptr->rigthchild,child2))
        {
            return ptr;
        }
        else
        {
            return FindComParent(ptr->leftchild,child1,child2);
        }
    }
    if(FindNode_Tree(ptr->rigthchild,child1))//not else //may be no this child in ptr
    {
        if(FindNode_Tree(ptr->leftchild,child2)) //右左
        {
            return ptr;
        }
        else
        {
            return FindComParent(ptr->rigthchild,child1,child2);
        }
    }

    return NULL;
}


//2
bool Get_Child_Tree_Path(BtNode *ptr,BtNode *child,list<BtNode*>& path) 
{
    if(ptr == NULL || child == NULL )
    {
        return false;
    }
    if(ptr == child)
    {
        path.push_back(ptr);
        return true;
    }
    path.push_back(ptr);
    bool found = false;
    found = Get_Child_Tree_Path(ptr->leftchild,child,path);
    if(!found)
    {
        found = Get_Child_Tree_Path(ptr->rigthchild,child,path);
    }
    if(!found)
    {
        path.pop_back();
    }

    return found;
}
BtNode * FindComParent2(BtNode *ptr, BtNode *child1,BtNode *child2)
{
    if(NULL == ptr || NULL == child1 || NULL == child2)
    {
        return NULL;
    }
    list<BtNode *>path1;
    list<BtNode *>path2;
    bool boolchild1 = Get_Child_Tree_Path(ptr,child1,path1);
    bool boolchild2 = Get_Child_Tree_Path(ptr,child2,path2);
    BtNode * last = NULL;
    if(boolchild1 && boolchild2)
    {

        list<BtNode *>::iterator it1 = path1.begin();
        list<BtNode *>::iterator it2 = path2.begin();
        while(it1 != path1.end() && it2 != path2.end())
        {
            if(*it1 ==  *it2)
            {
                last = *it1;
            }
            else
            {
                break;
            }
            ++it1;
            ++it2;
        }
    }
    else
    {
        last = NULL;
    }
    return last;
}
//转换成双链表
BtNode * BinaryTreeToList(BtNode *ptr)
{
    if(ptr == NULL )
    {
        return NULL;
    }
    BtNode *head = NULL;
    stack<BtNode*> st;
    while (ptr != NULL || !st.empty() )
    {
        while (ptr!=NULL)
        {
            st.push(ptr);
            ptr = ptr->leftchild;
        }
        BtNode *p = st.top();
        ptr = p;
        st.pop();

        if(NULL ==  head)
        {
            head = p;
            head->rigthchild = NULL;
            head->leftchild  = NULL;
        }
        else
        {
            BtNode *pre = head;
            while (pre->rigthchild != NULL)
            {
                pre = pre->rigthchild;
            }
            pre->rigthchild = p;
            p->leftchild    = pre;
            p->rigthchild   = NULL;
        }
        ptr = ptr->rigthchild;      
    }

    return head;
}
void BinaryTreeToList3(BtNode * &head,BtNode *&last)
{
    if(head == NULL) return;
    BinaryTreeToList3(head->leftchild,last);
    head->leftchild = last;
    if(last != NULL)
    {
        last->rigthchild = head;
    }
    last = head;
    BinaryTreeToList3(head->rigthchild,last);
}
void BinaryTreeToList2(BtNode * ptr,BtNode *&first,BtNode *&last)
{
    BtNode *pfirstleft;
    BtNode *plastleft;
    BtNode *pfirstright;
    BtNode *plastright;
    if(ptr == NULL)
    {
        first = NULL;
        last  = NULL;
        return ;
    }
    if(ptr->leftchild == NULL)
    {
        first = ptr;
    }
    else
    {
        BinaryTreeToList2(ptr->leftchild,pfirstleft,plastleft);
        first = pfirstleft;
        //把根节点放置到在左子树中查找到的最后一个节点
        ptr->leftchild        = plastleft;
        plastleft->rigthchild = ptr;
    }

    if(ptr->rigthchild == NULL)
    {
        last = ptr;
    }
    else
    {
        BinaryTreeToList2(ptr->rigthchild,pfirstright,plastright);
        last                   = plastright;
        ptr->rigthchild        = pfirstleft;
        pfirstleft->rigthchild = ptr;
    }
}

int main()
{
    //const char* p = "ABC##DE##F##G#H##"; 
    //BtNode * root = Create_Tree(p);
    //PreTree(root);
    //cout<<endl;
    //PreOrder2(root);
    //cout<<endl;
    //IsOrder(root);
    //PassTree_struct_pop_num(root);
    //int hight = 0;
    //if(IsBalance_BinaryTree(root,hight))
    //{
    //cout<<"root is IsBalance_BinaryTree"<<endl;
    //}

    const char *str1 = "ABC##D##EF###";
    const char *str2 = "ABCG###D##EF###";
    BtNode *root = Create_Tree(str1);

    IsOrder(root);
    BtNode *p;
    BtNode *q = NULL;
    BinaryTreeToList3(root,q);
    //BinaryTreeToList2(root,p,q);
    for(p = root;p!=NULL;p = p->rigthchild)
    {
        cout<<p->data<<" ";
    }
    cout<<endl;
    //cout<<p->data<<" "<<p->rigthchild->data<<" "<<p->rigthchild->rigthchild->data<<endl;
    //for(;p!=q;p = p->rigthchild)
    //{
    // cout<<p->data<<" ";
    //}
    //BtNode *root2 = Create_Tree(str2);
    ////PreTree(root);
    //
    //cout<<endl;
    //cout<<GetNumTree(root)<<endl;
    //BtNode * p = BinaryTreeToList(root); 
    //cout<<endl;

    //while (p!=NULL)
    //{
    // cout<<p->data<<" ";
    // p = p->rigthchild;
    //}
    //PassOrder(root);
    //if(Is_Comp_Binary_Tree(root))
    //{
    // cout<<"Ok Is_Comp_Binary_Tree"<<endl;
    //}
    //cout<<GetBinaryTreeLevel(root2,4)<<endl;
    /*PreTree(root2); cout<<endl; PassOrder(root2); if(Is_Comp_Binary_Tree(root2)) { cout<<"Ok Is_Comp_Binary_Tree"<<endl; }*/
    return 0;
}


//如果有什么错误,希望不吝赐教
点赞