二叉樹指針實現 根據中序和前序/後序得到一棵樹 並進行前中後序遍歷以及層序遍歷 並判斷完全,完滿,滿二叉樹

//輸入前序和中序得到整棵樹,並進行前中後序遍歷以及層序遍歷
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000+5;
struct BinaryTreeNode{
    int T_Value;
    BinaryTreeNode* T_Left;
    BinaryTreeNode* T_Right;
};
struct Node{
    BinaryTreeNode* TreeNode;
    int len;
};
//遞歸建樹
BinaryTreeNode* ConstructCore(BinaryTreeNode* PreRoot,int flag,int* startPre,int* endPre,int* startIn,int* endIn)
{
    int rootValue = startPre[0];
    BinaryTreeNode* root = new BinaryTreeNode();
    root->T_Value = rootValue;
    root->T_Left = root->T_Right = nullptr;
    if(flag==1&&PreRoot!=nullptr) {
        PreRoot->T_Left = root;
    }
    else if(flag==0&&PreRoot!=nullptr) {
        PreRoot->T_Right = root;
    }
    //如果只剩下一個根節點
    if(startPre==endPre&&startIn==endIn&&*startPre==*endPre&&*startIn==*endIn&&*startPre==*endIn)
    {
        return root;
    }
    //在中序遍歷中找到這個根節點
    int* rootNode = startIn;
    while(rootNode<endIn&&*rootNode!=rootValue)
    {
        rootNode++;
    }
    if(rootNode==endIn&&*rootNode!=rootValue)
    {
        printf("the input is wrong!!!\n");
        return root;
    }
    //遞歸構建左右子樹
    int LeftLength = rootNode - startIn;
    int RightLength = endIn - rootNode;
    int* RightPreStart = startPre+LeftLength+1;
    if(LeftLength>0)
    {
        ConstructCore(root,1,startPre+1,startPre+LeftLength,startIn,rootNode-1);
    }
    if(RightLength>0)
    {
        ConstructCore(root,0,RightPreStart,endPre,rootNode+1,endIn);
    }
    return root;
}
BinaryTreeNode* Construct(int* Pre,int* In,int length)
{
    if(Pre==nullptr||In==nullptr||length<=0) return nullptr;
    return ConstructCore(nullptr,-1,Pre,Pre+length-1,In,In+length-1);
}
//前序遍歷
void dfsPreOrder(BinaryTreeNode* root,int deep)
{
    if(root==nullptr) {
        return;
    }
    printf("%d %d\n",root->T_Value,deep);
    dfsPreOrder(root->T_Left,deep+1);
    dfsPreOrder(root->T_Right,deep+1);
}
//中序遍歷
void dfsInOrder(BinaryTreeNode* root,int deep)
{
    if(root==nullptr) {
        return;
    }
    dfsInOrder(root->T_Left,deep+1);
    printf("%d %d\n",root->T_Value,deep);
    dfsInOrder(root->T_Right,deep+1);
}
//後序遍歷
void dfsLastOrder(BinaryTreeNode* root,int deep)
{
    if(root==nullptr) {
        return;
    }
    dfsLastOrder(root->T_Left,deep+1);
    dfsLastOrder(root->T_Right,deep+1);
    printf("%d %d\n",root->T_Value,deep);
}
//層序遍歷       bfs
void bfsTree(BinaryTreeNode* root,int deep)
{
    queue<Node>pq;
    while(!pq.empty()) pq.pop();
    Node now ;
    now.TreeNode = root;
    now.len = deep;
    pq.push(now);
    while(!pq.empty())
    {
        Node node = pq.front();
        pq.pop();
        printf("%d %d\n",node.TreeNode->T_Value,node.len);
        if(node.TreeNode->T_Left!=nullptr) {
            now.len = node.len+1;
            now.TreeNode = node.TreeNode->T_Left;
            pq.push(now);
        }
        if(node.TreeNode->T_Right!=nullptr) {
            now.len = node.len+1;
            now.TreeNode = node.TreeNode->T_Right;
            pq.push(now);
        }
    }
}
int main()
{
    int n;
    scanf("%d",&n);
    int Pre[maxn],In[maxn];
    for(int i = 0;i<n;i++)
    {
        scanf("%d",&Pre[i]);
    }
    for(int i = 0;i< n;i++)
    {
        scanf("%d",&In[i]);
    }
    BinaryTreeNode* root = Construct(Pre,In,n);
    printf("樹的前序遍歷及各節點高度:\n");
    dfsPreOrder(root,1);
    printf("樹的中序遍歷及各節點高度:\n");
    dfsInOrder(root,1);
    printf("樹的後序遍歷及各節點高度:\n");
    dfsLastOrder(root,1);
    printf("樹的層序遍歷及各節點高度:\n");
    bfsTree(root,1);
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
//構建二叉樹  並進行二叉樹的前序遍歷 中序遍歷 後序遍歷 層序遍歷.
const int maxn = 100+5;
struct TreeNode{
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x):val(x),left(nullptr),right(nullptr){}
    TreeNode():val(),left(nullptr),right(nullptr){}
};
class Solution{
public:
    Solution()
    {

    }
    ~Solution()
    {

    }
    //前序遍歷
    void PreOrder(TreeNode* root,vector<int>& vec)
    {
        if(root==nullptr) return;
        vec.push_back(root->val);
        PreOrder(root->left,vec);
        PreOrder(root->right,vec);
    }
    //中序遍歷
    void InOrder(TreeNode* root,vector<int>& vec)
    {
        if(root==nullptr) return;
        InOrder(root->left,vec);
        vec.push_back(root->val);
        InOrder(root->right,vec);
    }
    //後序遍歷
    void AfterOrder(TreeNode* root,vector<int>& vec)
    {
        if(root==nullptr) return;
        AfterOrder(root->left,vec);
        AfterOrder(root->right,vec);
        vec.push_back(root->val);
    }
    //層序遍歷
    void bfsOrder(TreeNode* root,vector<int>& vec)
    {
        if(root==nullptr) return;
        queue<TreeNode*>pq;
        while(!pq.empty()) pq.pop();
        pq.push(root);
        while(!pq.empty())
        {
            TreeNode* now = pq.front();
            pq.pop();
            vec.push_back(now->val);
            if(now->left!=nullptr) {
                pq.push(now->left);
            }
            if(now->right!=nullptr) {
                pq.push(now->right);
            }
        }
    }
    bool BfsCom_Bin_Tree(TreeNode* root)
    {
        if(root==nullptr) return false;
        queue<TreeNode*> pq;
        while(!pq.empty()) pq.pop();
        pq.push(root);
        bool flag = false;
        while(!pq.empty())
        {
            TreeNode* now = pq.front();
            pq.pop();
            if(flag) {
                if(now->left!=nullptr||now->right!=nullptr) return false;
            }
            if(now->left!=nullptr) {
                if(now->right==nullptr) {
                    flag =true;
                    pq.push(now->left);
                }
                else {
                        pq.push(now->left);
                        pq.push(now->right);
                }
            }
            else {
                if(now->right==nullptr) {
                    flag = true;
                }
                else {
                    return false;
                }
            }
        }
        return true;
    }
    // 判斷是否是完全二叉樹
    //使用層序遍歷,如果當前節點只有右節點,那麼一定不是完全二叉樹,否則,如果當前節點只有左節點或者無節點,那麼這個節點後面的所有節點均爲葉子節點
    bool Complete_Binary_Tree(TreeNode* root)
    {
        if(root==nullptr) return false;
        return BfsCom_Bin_Tree(root);
    }

    bool BfsFull_Bin_Tree(TreeNode* root)
    {
        if(root==nullptr) return false;
        bool flag = false;
        int deep = 1;
        queue<pair<TreeNode*,int> > pq;
        while(!pq.empty()) pq.pop();
        pq.push(make_pair(root,1));
        while(!pq.empty())
        {
            pair<TreeNode*,int>node;
            node = pq.front();
            pq.pop();
            if(flag) {
                if(deep<node.second) return false;
            }
            if((node.first->left!=nullptr&&node.first->right==nullptr)||(node.first->left==nullptr&&node.first->right!=nullptr)) return false;
            if(node.first->left==nullptr&&node.first->right==nullptr) {
                    flag = true;                //表示到達葉子層
                    deep = node.second;
                    continue;
            }
            pq.push(make_pair(node.first->left,node.second+1));
            pq.push(make_pair(node.first->right,node.second+1));
        }
        return true;
    }
    //判斷是否是滿二叉樹
    //要根據層數來判斷,如果當前層不是葉子層,那麼必須每個節點都有兩個子節點
    //否則,每個節點都必須沒有子節點,而且,如果判斷出來的葉子層不是最高的一層,那麼也不是滿二叉樹
    bool Full_Binary_Tree(TreeNode* root)
    {
        if(root==nullptr) return false;
        return BfsFull_Bin_Tree(root);
    }

    bool BfsNot_Com_Bin_Tree(TreeNode* root)
    {
        if(root==nullptr) return false;
        queue<TreeNode*>pq;
        while(!pq.empty()) pq.pop();
        pq.push(root);
        while(!pq.empty())
        {
            TreeNode* now = pq.front();
            pq.pop();
            if((now->left!=nullptr&&now->right==nullptr)||(now->left==nullptr&&now->right!=nullptr)) return false;
            if(now->left!=nullptr) pq.push(now->left);
            if(now->right!=nullptr) pq.push(now->right);
        }
        return true;
    }
    //判斷是否是完滿二叉樹
    //每個節點不然有兩個子節點,不然有0個子節點
    bool Not_Complete_Binary_Tree(TreeNode* root)
    {
        if(root==nullptr) return false;
        return BfsNot_Com_Bin_Tree(root);
    }
    //構建二叉樹
    TreeNode* ConstructCore(int startpre,int endpre,int startin,int endin,int (&pre)[maxn],int (&in)[maxn],TreeNode* parent,int flag)
    {
        if(startpre>endpre||startin>endin) return nullptr;
        int value = pre[startpre];
        TreeNode* now = new TreeNode(value);
        if(parent!=nullptr) {
            if(flag==-1) {
                parent->left = now;
            }
            else if(flag==1) {
                parent->right = now;
            }
        }
        //找到當前點的左右子樹,並進行遞歸構建左右子樹
        int index = startin;
        while(index<endin&&in[index]!=value) index++;
        if(index==endin&&in[index]!=value) return nullptr;
        //找到中序遍歷中根節點,那麼此時可以判斷左右子樹範圍
        int leftLength = index - startin;
        int rightLength = endin - index;
        //遞歸構建左右子樹
        if(leftLength>0) {
            ConstructCore(startpre+1,startpre + leftLength , startin,index-1,pre,in,now,-1);
        }
        if(rightLength>0) {
            ConstructCore(startpre+leftLength+1,endpre,index+1,endin,pre,in,now,1);
        }
        return now;
    }
    TreeNode* Construct(int startpre,int endpre,int startin,int endin,int (&pre)[maxn],int (&in)[maxn],int n)
    {
        if(n<=0) return nullptr;
        return ConstructCore(startpre,endpre,startin,endin,pre,in,nullptr,-2);
    }
};
int main()
{
    int n;
    scanf("%d",&n);
    int pre[maxn],in[maxn];
    for(int i = 0;i<n;i++)
        scanf("%d",&pre[i]);
    for(int i=0;i<n;i++)
        scanf("%d",&in[i]);
    Solution* sol = new Solution();
    TreeNode* root = nullptr;
    root = sol->Construct(0,n-1,0,n-1,pre,in,n);
    vector<int>solve;
    solve.clear();
    sol->PreOrder(root,solve);
    for(int i=0;i<solve.size();i++)
        cout<<solve[i]<<" ";
    cout<<endl;
    solve.clear();
    sol->InOrder(root,solve);
    for(int i=0;i<solve.size();i++)
        cout<<solve[i]<<" ";
    cout<<endl;
    solve.clear();
    sol->AfterOrder(root,solve);
    for(int i=0;i<solve.size();i++)
        cout<<solve[i]<<" ";
    cout<<endl;
    solve.clear();
    sol->bfsOrder(root,solve);
    for(int i=0;i<solve.size();i++)
        cout<<solve[i]<<" ";
    cout<<endl;
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章