二叉树 C++

代码参考:

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

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

二叉树的性质:

1、在二叉树的第 i 层上,至多有 2 i-1  个节点。(i >= 1)
2、深度为 k 的二叉树至多有 2k -1 个节点 (k >= 1)
3、对任何一棵二叉树 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

4、具有 N 个结点的完全二叉树的深度为【log N】 + 1. (【X】表示不大于X 的最大整数,底是2)

证明:    2k-1 -1 < N <= 2k -1
              2k-1 <= N < 2k
              对两边取对数
              k -1 <= log N < k             k = 【log N】 + 1

5、如果对一棵有 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;

二叉树类的声明:包括树的建立、递归遍历、非递归遍历、结点总数、叶子节点数、树的高度

#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非空时, 1、打印根节点,并把根结点压入栈    2、将左叶子节点复制给 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
原文地址:https://www.cnblogs.com/hello-gogo/p/7234851.html