1、树的存储:

 

注意:树的深度是从根节点开始(其深度为1)自顶向下逐层累加的,而高度是从叶节点开始(其高度为1)自底向上逐层累加的。虽然树的深度和高度一样,但是具体到树的某个节点,其深度和高度是不一样的。我的理解是:非根非叶结点的深度是从根节点数到它的,高度是从叶节点数到它的。

二叉树的存储:1、数组存储(此方法适合完全二叉树的存储)

                   2、链表存储(可分为二叉链表,三叉链表)结构如下:

 

2、 使用二叉链表实现二叉树

 测试用例:

int a[10] = { 1, 2, '#', '#', 3, 4, '#', '#', 5, 6 };//其中用'表示空'

按前序遍历的算法重建出二叉树为:(先创建根节点,再创建左子树,后创建右子树)

                                            

代码实现:

BinaryTree<T>* _CreateBinaryTree(const T *a,size_t size, size_t&index)
    {
        assert(a);
        BinaryTreeNode<T> *node = new BinaryTreeNode<T> (a[index]);
        if (index < size&&a[index++] != '#')
        {
            node->_left = _CreateBinaryTree(a, size, ++index);
           node->_right = _CreateBinaryTree(a, size, ++index);

        }
        else
{
return NULL;
}
return node; }

 3、二叉树的遍历

以上图的二叉树为例:

1-a、先序遍历(由于二叉树的结构具有递归的特性可以采用递归的方式遍历)

void _PrevOrder(BinaryTreeNode<T>* root)
    {
        if (root)
        {
            cout<<root->_data<<" ";
            _PrevOrder(root->_left);
            _PrevOrder(root->_right);
        }
        else
             return;
        
    }

1-b、二叉树的非递归先序遍历
思想:1、可以采用栈先进先出的原则:先使根节点入栈,栈不为空打印栈顶元素,弹出栈顶元素,

         2、在使栈顶元素的不为空右子树入栈,再使栈顶元素的不为空左子树入栈

         3、 再按1、2进行判断直至栈为空退出

void PrevOrder_NonR(BinaryTreeNode<T> *_root)
    {
        if (_root==NULL)
        {
            return;
        }
        stack<BinaryTreeNode<T>*> s1;
        s1.push(_root);
        while (!s1.empty())
        {
            BinaryTreeNode<T> *top=s1.top();
            cout<<top->_data<<" ";
            s1.pop();
            if (top->_right)
            {
                s1.push(top->_right);
            }
            if (top->_left)
            {
                s1.push(top->_left);
            }
        }
        cout<<endl;
    }

2-a、二叉树的中序遍历(递归)

void _InOrder(BinaryTreeNode<T>* root)
    {
        if (root)
        {
            _InOrder(root->_left);
            cout<<root->_data<<" ";
            _InOrder(root->_right);
        }
        else
        {
            return;
        }
    }

2-b、二叉树的中序遍历非递归

思想:中序遍历是先遍历左子树,再遍历根节点,后遍历右子树

        1、使cur指向根节点,使cur->_left入栈直至cur为空(定义cur是为了指向当前遍历的节点)

        2、若栈不为空,打印栈顶元素,使cur指向栈顶元素的右子树(当前的栈顶元素也就是某一个树的根节点,但其右子树还未遍历所以使cur指向其右子树)

        3-a、若栈不为空,前一步栈顶元素的右子树为空,直接打印当前栈顶元素也就是前一步栈顶元素的根节点

        3-b、若栈不为空,前一步栈顶元素的右子树不为空,使cur指向的右子树入栈

        4、在按照2,3的步骤循环,直至cur和栈为空时结束

//非递归中序
    void InOrder_NonR(BinaryTreeNode<T> *root)
    {
        stack<BinaryTreeNode<T>*> s1;
        BinaryTreeNode<T>* cur=_root;
        while (cur||!s1.empty())
        {
            while (cur)
            {
                s1.push(cur);
                cur=cur->_left;
            }
            if (!s1.empty())
            {
                BinaryTreeNode<T>* top=s1.top();
                cout<<top->_data<<" ";
                s1.pop();
                cur=top->_right;
            }

        }
        cout<<endl;
    }

3-a二叉树的后续遍历(递归)

void _PostOrder(BinaryTreeNode<T>* root)
    {
        if (root)
        {
            _PostOrder(root->_left);
            _PostOrder(root->_right);
            cout<<root->_data<<" ";
        }
        else
        {
            return;
        }
    }

 

posted on 2016-06-19 17:26  My_Blog_Days  阅读(2359)  评论(0编辑  收藏  举报