二叉樹 C++

代碼參考:node

http://blog.csdn.net/iqrocket/article/details/8266365ios

http://blog.csdn.net/luno1/article/details/7951993ide

二叉樹的性質:函數

一、在二叉樹的第 i 層上,至多有 2 i-1  個節點。(i >= 1)
二、深度爲 k 的二叉樹至多有 2k -1 個節點 (k >= 1)
三、對任何一棵二叉樹 T,若是其終端節點數爲 n0, 度爲2 的節點數爲 n2, 則 n0 = n2 +1
證實: 分支線總數是 W, 節點總數是 N, 度爲1的節點是 n1。  W = N -1
      W = N -1 = n1 + 2*n2
      N = n0 + n1 + n2
      => n0 = n2 + 1測試

四、具備 N 個結點的徹底二叉樹的深度爲【log N】 + 1. (【X】表示不大於X 的最大整數,底是2)spa

證實:    2k-1 -1 < N <= 2k -1
              2k-1 <= N < 2k
              對兩邊取對數
              k -1 <= log N < k             k = 【log N】 + 1.net

五、若是對一棵有 N 個結點的徹底二叉樹(其深度爲【log n】+ 1)的結點按層序編號(從第一層到第【log n】+ 1 層,每層從左到右),對任一結點 i (1<= i<=n)有:
a: 若是 i = 1, 則結點 i 是二叉樹的根,無雙親;若是 i>1,則其雙親是結點【i/2】
b: 若是2i > n, 則結點 i 無左孩子(結點 i 爲葉子結點);不然其左孩子是結點 2i;
c: 若是2i+1 > n,則結點 i 無右孩子(結點 i 爲葉子結點);不然其左孩子是結點 2i+1;code

二叉樹類的聲明:包括樹的創建、遞歸遍歷、非遞歸遍歷、結點總數、葉子節點數、樹的高度blog

#include<iostream>
#include<stack>
#include<queue>
using namespace std;
template<class T>
struct TreeNode
{
    T element;
    TreeNode* rightNode, *leftNode;
};

template<class T>
class BinaryTree
{
public:
    BinaryTree();
    ~BinaryTree();
    TreeNode<T>*GetRoot();
    //遞歸遍歷
    void PreOrder(TreeNode<T>*);
    void Inorder(TreeNode<T>*);
    void PostOrder(TreeNode<T>*);
    //非遞歸遍歷
    void NonPreOrder(TreeNode<T>*);
    void NonInOrder(TreeNode<T>*);
    void NonPostOrder(TreeNode<T>*);
    void LevelOrder(TreeNode<T>*);    //層序遍歷

    int BTreeSize(TreeNode<T>*);       //計算樹的節點總數
    int BTreeLeaves(TreeNode<T>*);     //計算樹的葉子數
     int BTreeHight(TreeNode<T>*);      //計算樹的高度

private:
    TreeNode<T>* root;
    TreeNode<T>*Create();
    void Release(TreeNode<T>*root);
};

二叉樹中函數的實現:遞歸

//獲取根結點
template<class T>
TreeNode<T>* BinaryTree<T>::GetRoot()
{
    return root;
}
//構造函數
template<class T>
BinaryTree<T>::BinaryTree()
{
    root = new TreeNode<T>;
    root = Create();
}
//析構函數
template<class T>
BinaryTree<T>::~BinaryTree()
{
    Release(root);
    delete root;
}
//生成樹,採用先序遍歷的方式生成樹
template<class T>
TreeNode<T>* BinaryTree<T>::Create()
{
    char elem;
    cin >> elem;
    TreeNode<T>* node;
    if (elem == '#')
        node = NULL;
    else
    {
        node = new TreeNode<T>;
        node->element = elem;
        node->leftNode = Create();
        node->rightNode = Create();
    }
    return node;
}
//刪除結點
template<class T>
void BinaryTree<T>::Release(TreeNode<T>*root)
{
    if (root != NULL)
    {
        Release(root->leftNode);
        Release(root->rightNode);
    }
}
//前序遍歷
template<class T>
void BinaryTree<T>::PreOrder(TreeNode<T>*node)
{
    if (node == NULL)
        return;
    else
    {
        cout << node->element<<"  ";
        PreOrder(node->leftNode);
        PreOrder(node->rightNode);
    }
}
//中序遍歷
template<class T>
void BinaryTree<T>::Inorder(TreeNode<T>*node)
{
    if (node == NULL)
        return;
    else
    {
        Inorder(node->leftNode);
        cout << node->element << "  ";
        Inorder(node->rightNode);
    }
}
//後序遍歷
template<class T>
void BinaryTree<T>::PostOrder(TreeNode<T>*node)
{
    if (node == NULL)
        return;
    else
    {
        PostOrder(node->leftNode);
        PostOrder(node->rightNode);
        cout << node->element<<"  ";
    }
}

template<class T>
void BinaryTree<T>::NonPreOrder(TreeNode<T>*node)
{
    //前序遍歷的順序是:根左右
    stack<TreeNode<T>*>s;
    TreeNode<T>*pNode = node;
    while (pNode != NULL || !s.empty())
    {
        while (pNode != NULL)   //當pNode非空時, 一、打印根節點,並把根結點壓入棧    二、將左葉子節點複製給 pNode,
        {
            cout << pNode->element << "  ";
            s.push(pNode);
            pNode = pNode->leftNode;
        }
        if (!s.empty())        //當棧非空時,將棧頂元素的右葉子複製給 pNode
        {
            pNode = s.top();
            s.pop();
            pNode = pNode->rightNode;
        }
    }
}

//非遞歸中序遍歷
template<class T>
void BinaryTree<T>::NonInOrder(TreeNode<T>*node)     
{
    stack<TreeNode<T>*>s;
    TreeNode<T>*pNode = node;
    while ( pNode != NULL || !s.empty())
    {
        while (pNode != NULL)
        {
            s.push(pNode);
            pNode = pNode->leftNode;
        }
        if (!s.empty())
        {
            pNode = s.top();
            cout << pNode->element << "  ";
            s.pop();
            pNode = pNode->rightNode;
        }
    }
}

//非遞歸後序遍歷
template<class T>
void BinaryTree<T>::NonPostOrder(TreeNode<T>*node)
{
    //遍歷順序:左右跟
    /*
         對任一結點,先將其入棧,訪問該結點的左節點和右節點。若左右結點均訪問過,則訪問該節點
    */
    if (node == NULL)
        return;
    stack<TreeNode<T>*>s;
    queue<TreeNode<T>*>q;
    s.push(node);                 //將根結點壓入棧
    TreeNode<T>*pre = NULL;
    TreeNode<T>* cur;
    while (!s.empty())
    {
        cur = s.top();
        //上一次訪問的是當前節點的左子樹
        if (cur->leftNode == NULL&&cur->rightNode == NULL || (pre != NULL) && (pre == cur->leftNode || pre == cur->rightNode))
        {
            cout << cur->element << "  ";
            s.pop();
            pre = cur;
        }
        else
        {
            if (cur->rightNode)
                s.push(cur->rightNode);
            if (cur->leftNode)
                s.push(cur->leftNode);
        }
    }

}

//層序遍歷
template<class T>
void BinaryTree<T>::LevelOrder(TreeNode<T>*node)   //層序遍歷
{
    TreeNode<T>*pNode = node;
    if (pNode == NULL)
        return;
    //將每次層的葉子節點進入隊列
    queue<TreeNode<T>*>q;
    q.push(pNode);
    while (!q.empty())
    {
        pNode = q.front();
        cout << pNode->element << "  ";
        q.pop();
        if (pNode->leftNode)
            q.push(pNode->leftNode);
        if (pNode->rightNode)
            q.push(pNode->rightNode);
    }
}


//求二叉樹結點個數的函數  
template<class T>
int BinaryTree<T>::BTreeSize(TreeNode<T>* node)
{
    //二叉樹的結點個數爲左右子樹的高度之和再+1  
    if (node == NULL)
        return 0;
    else
        return 1 + BTreeSize(node->leftNode) + BTreeSize(node->rightNode);
}


//求二叉樹葉子結點個數的函數  
template<class T>
int BinaryTree<T>::BTreeLeaves(TreeNode<T>* node)
{
    //當爲空時,返回0;當找到葉子時返回1  
    if (node == NULL) 
        return 0;
    else
       if (node->leftNode == 0 && node->rightNode == 0)
            return 1;
       else
           return BTreeLeaves(node->leftNode) + BTreeLeaves(node->rightNode);
}

//求二叉樹高度的函數  
template<class T>
int BinaryTree<T>::BTreeHight(TreeNode<T>* node)
{
    if (node == NULL) 
        return 0;
    else
    {
        //二叉樹的高度爲左右子樹的最大者+1  
        int lHei = BTreeHight(node->leftNode);
        int rHei = BTreeHight(node->rightNode);
        return (lHei>rHei) ? lHei + 1 : rHei + 1;
    }
}
View Code

測試代碼:輸入: A B # D # C # #。 樹的形式爲:

#include<iostream>
#include<string>
#include"BinaryTree.cpp"
using namespace std;

int main()
{
    cout << "請輸入節點" << endl;   // A B # D # C # #
    BinaryTree<char>my_tree;
    
    my_tree.PreOrder(my_tree.GetRoot());
    cout << "遞歸先序遍歷" << endl;

    my_tree.Inorder(my_tree.GetRoot());
    cout << "遞歸中序遍歷" << endl;
    
    my_tree.PostOrder(my_tree.GetRoot());
    cout << "遞歸後序遍歷" << endl;

    my_tree.LevelOrder(my_tree.GetRoot());
    cout << "層序遍歷" << endl;


    my_tree.NonPreOrder(my_tree.GetRoot());
    cout << "非遞歸先序遍歷" << endl;

    my_tree.NonInOrder(my_tree.GetRoot());
    cout << "非遞歸中序遍歷" << endl;

    my_tree.NonPostOrder(my_tree.GetRoot());
    cout << "非遞歸後序遍歷" << endl;

    cout << "二叉樹的節點數是: " << my_tree.BTreeSize(my_tree.GetRoot()) << endl;
    cout << "二叉樹的葉子數是: " << my_tree.BTreeLeaves(my_tree.GetRoot()) << endl;
    cout << "二叉樹的高度是: " << my_tree.BTreeHight(my_tree.GetRoot()) << endl;

    cout << endl;
    cout << "hello world" << endl;
    system("pause");
    return 0;
}
View Code
相關文章
相關標籤/搜索