二叉树的递归和非递归

来源:互联网 发布:幕墙光污染模拟软件 编辑:程序博客网 时间:2024/04/30 00:49

二叉树的几种遍历算法

1.二叉树的前序遍历
2.二叉树的中序遍历
3.二叉树的后序遍历
4 .二叉树的后序遍历

一. 二叉树的前序遍历
前序遍历算法是判断节点是否为空,如果不为空,先访问根节点,再访问左子树,最后访问右子树;
前序的递归: 根->左子树(为空)->右子树。对于每一个子树又可以用同样的访问顺序来遍历。

void PrevOrder()    {        _PrevOrder(_root);        cout << endl;    }

具体实现:

void _PrevOrder(Node *root)    {        Node *cur = root;        if (cur == NULL)        {            return ;        }        cout << cur->_data << " ";        _PrevOrder(cur->_left);        _PrevOrder(cur->_right);    }

前序的非递归算法
对于任意节点cur:
1:判断根节点是否为空,空则返回
2:根节点不为空,输出节点,将根节点入栈,再看cur的左子树是否为空。
3:若cur的左子树不为空,将cur左子树置为当前节点,重复3操作。
4:若cur的左子树为空,将栈顶节点出栈,但不输出,将右子树的节点置为当前节点,看右子树是否为空。
5:不为空重复3操作
6:为空重复4操作
7:直到当前节点为NULL,且栈为空,则遍历结束。
前序

void PrevOrder_NotR()    {        cout << "前序非递归" << endl;        return _PrevOrder_NotR(_root);        cout << endl;    }`void _PrevOrder_NotR(Node *root){if (root == NULL)//空树{return;}Node*cur = root;stack<Node*> s;while ( !s.empty()||cur!= NULL){//边遍历边将节点压栈while(cur){cout << cur->_data << " ";s.push(cur);//根节点入栈cur = cur->_left;}//说明此时左子树已经遍历完了,要遍历要遍历右子树if (!s.empty()){cur = s.top();//取栈顶元素s.pop();//出栈cur = cur->_right;}}cout << endl;}

二:二叉树的中序遍历****
二叉树的中序遍历算法:先访问左子树,再访问根节点,最后访问右子树。
中序:

void InOrder(){_InOrder(_root);cout << endl;}

实现:

void _InOrder(Node *root)    {        Node *cur = root;        if (cur == NULL)        {            return;        }        _InOrder(cur->_left);        cout << cur->_data << " ";        _InOrder(cur->_right);    }

中序的非递归算法:
对于任意节点cur:
1:cur是否为空若为空返回。
2:cur不为空,判断cur的左子树是否为空,若不为空,将cur入栈,将cur的左子树置为当前节点。并对当前节点进行相同操作。
3:cur的左子树为空,输出cur,并将cur的右子树当前节点,看是否为空。
4:不为空重复2和3操作。
5:为空,则执行出栈操作,输出栈顶结点,并将右孩子置为当前节点,看是否为空重复3和4操作。
6:直到当前节点P为NULL并且栈为空,则遍历结束
非递归的实现:

void _InOrder_NotR(Node*root)    {        Node*cur = root;        if (cur == NULL)        {            return;        }        stack<Node *> s;        while (cur!= NULL||!s.empty())        {            //一直遍历到左子树的最下面            while (cur)            {                s.push(cur);                cur = cur->_left;            }            //说明左子树已经遍历完了;这时需要出栈            if (!s.empty())            {                cur = s.top();                s.pop();                cout << cur->_data << " ";                //遍历右子树                cur = cur->_right;            }        }        cout << endl;    }

三:二叉树的后序遍历:
后序遍历算法:根节点->右子树->左子树
后序的递归:

void PosOrder()    {        _PosOrder(_root);        cout << endl;    }

实现:

void _PosOrder(Node *root)    {        Node *cur = root;        if (cur == NULL)        {            return;        }        _PosOrder(cur->_right);        cout << cur->_data << " ";        _PosOrder(cur->_left);    }

后序的非递归算法:
对于任意节点cur:
1:cur是否为空若为空返回。
2:cur不为空,判断cur的右子树是否为空,若不为空,将cur入栈,将cur的右子树置为当前节点。并对当前节点进行相同操作。
3:cur的右子树为空,输出cur,并将cur的左子树当前节点,看是否为空。
4:不为空重复2和3操作。
5:为空,则执行出栈操作,输出栈顶结点,并将左孩子置为当前节点,看是否为空重复3和4操作。
6:直到当前节点P为NULL并且栈为空,则遍历结束
非递归的实现:

//后序非递归    void _PosOrder_NotR(Node*root)    {        Node*cur = root;        if (cur == NULL)//空树        {            return;        }        stack<Node*>s;        while (!s.empty() || cur!=NULL)        {            //一直遍历右子树的最下面,边遍历边将节点压栈            while (cur)            {                s.push(cur);                cur=cur->_right;            }            if (!s.empty())            {                //右子树已经遍历完了,                cur = s.top();                s.pop();                cout << cur->_data << " ";                //遍历左子树                cur = cur->_left;            }        }        cout << endl;    }

四:二叉树的层序遍历:
我们可以利用队的先进先出的性质,具体实现是,先遍历当前层,入队,然后遍历下一层。置到结束:
实现:

void _LevelOeder(Node *root)    {        queue<Node *> q;        if (root == NULL)        {            return;        }        if (root)        {            q.push(root);//把根节点入队        }        while (!q.empty())        {            Node*front = q.front();            cout << front->_data << " ";            q.pop();            if (front->_left)                q.push(front->_left);//左子树入队            if (front->_right)                q.push(front->_right);//右子树入队        }        cout << endl;    }

五:实现及其测试函数:
.h文件

#pragma once#include<queue>#include<stack>#include<assert.h>using namespace std;template<class T>struct BinaryTreeNode{    T _data;//数据    BinaryTreeNode<T>* _left;//左节点    BinaryTreeNode<T>* _right;//右节点    BinaryTreeNode(const T&x =T())        :_data(x)        , _left(NULL)        , _right(NULL)    {}};template<class T>class BinaryTree{    typedef BinaryTreeNode<T>  Node;public:    BinaryTree()        :_root(NULL)    {}    BinaryTree(const BinaryTree<T> &t)    {        _root = _copy(t._root);    }    BinaryTree<T>&operator = (BinaryTree<T> &t)    {        //BinaryTree<T> tmp(t._root);        swap(_root, t._root);        return *this;    }    ~BinaryTree()    {        _Destroy(_root);    }    BinaryTree(const T*a, size_t n, const T&invalued = T())    {        size_t indes = 0;        _root = _CreatTree(a, n, indes, invalued);//创建一个二叉树    }    //数节点的个数    size_t Size()    {        return _Size(_root);    }    //深度    size_t Depth()    {        return _Depth(_root);    }    //叶子节点的个数    size_t LeftSize()    {        return _LeftSize(_root);    }    //获取k的节点    int GetkLevel(Node *root, int k)    {        if (root == NULL||k<1)        {            return 0;        }        if (k == 1)        {            return 1;        }        int leftGetkLevel = GetkLevel(root->_left, k - 1);        int rightGetkLevel = GetkLevel(root->_right, k - 1);        return (leftGetkLevel + rightGetkLevel);    }    //前序    void PrevOrder()    {        _PrevOrder(_root);        cout << endl;    }    //前序非递归    void PrevOrder_NotR()    {        cout << "前序非递归" << endl;        return _PrevOrder_NotR(_root);        cout << endl;    }    //中序    void InOrder()    {        _InOrder(_root);        cout << endl;    }    //中序非递归    void InOrder_NotR()    {        cout << "中序非递归" << endl;        return _InOrder_NotR(_root);        cout << endl;    }    //后序    void PosOrder()    {        _PosOrder(_root);        cout << endl;    }    //后序非递归    void PosOrder_NotR()    {        cout << "后序非递归" << endl;        return _PosOrder_NotR(_root);        cout << endl;    }    //层序    void LevelOrder()    {        _LevelOeder(_root);        cout << endl;    }protected:    Node*_CreatTree(const T*a, size_t n, size_t &indes, const T&invalued)     {        assert(a);        Node* root = NULL;        if (indes<n && a[indes] != invalued)        {            root = new Node(a[indes]);//创建根节点            root->_left = _CreatTree(a, n,++indes,invalued);            root->_right= _CreatTree(a, n,++indes,invalued);        }        return root;    }    //拷贝    Node *_copy(Node *node)    {        Node*cur = node;        Node root = NULL;//        if (cur)        {            root = new Node(cur->_data);//创建新节点            root->_left = _copy(cur->_left);//递归调用            root->_right = _copy(cur->_right);//递归调用        }        return root;    }    //删除    void _Destroy(Node *node)    {        Node* del = node;        if (del)        {            _Destroy(del->_left);            _Destroy(del->_right);            delete del;            del = NULL;        }    }    //树节点的个数    size_t _Size(Node *root)    {        if (root == NULL)        {            return 0;        }        return _Size(root->_left) + _Size(root->_right) + 1;    }    //深度    size_t _Depth(Node *root)    {        Node *cur = root;        if (cur == NULL)        {            return 0;        }        //比较左子树和右子树的大小        return 1 + (_Depth(cur->_left) > _Depth(cur->_right)             ? _Depth(cur->_left) : _Depth(cur->_right));    }    //叶子节点的个数    size_t _LeftSize(Node *root)    {        Node*cur = root;        if (NULL == cur)//空树        {            return 0;        }        if (cur->_left == NULL&&cur->_right == NULL)//只有根节点        {            return 1;        }        return _LeftSize(cur->_left)+_LeftSize(cur->_right);//左子树与右子树的和    }    //前序    void _PrevOrder(Node *root)    {        Node *cur = root;        if (cur == NULL)        {            return ;        }        cout << cur->_data << " ";        _PrevOrder(cur->_left);        _PrevOrder(cur->_right);    }    //前序非递归    void _PrevOrder_NotR(Node *root)    {        if (root == NULL)//空树        {            return;        }        Node*cur = root;        stack<Node*> s;        while ( !s.empty()||cur!= NULL)        {            //边遍历边将节点压栈            while(cur)            {                cout << cur->_data << " ";                s.push(cur);//根节点入栈                cur = cur->_left;            }            //说明此时左子树已经遍历完了,要遍历要遍历右子树            if (!s.empty())            {                cur = s.top();//取栈顶元素                s.pop();//出栈                cur = cur->_right;            }        }        cout << endl;    }    //中序    void _InOrder(Node *root)    {        Node *cur = root;        if (cur == NULL)        {            return;        }        _InOrder(cur->_left);        cout << cur->_data << " ";        _InOrder(cur->_right);    }    //中序非递归    void _InOrder_NotR(Node*root)    {        Node*cur = root;        if (cur == NULL)        {            return;        }        stack<Node *> s;        while (cur!= NULL||!s.empty())        {            //一直遍历到左子树的最下面            while (cur)            {                s.push(cur);                cur = cur->_left;            }            //说明左子树已经遍历完了;这时需要出栈            if (!s.empty())            {                cur = s.top();                s.pop();                cout << cur->_data << " ";                //遍历右子树                cur = cur->_right;            }        }        cout << endl;    }    //后序    void _PosOrder(Node *root)    {        Node *cur = root;        if (cur == NULL)        {            return;        }        _PosOrder(cur->_right);        cout << cur->_data << " ";        _PosOrder(cur->_left);    }    //后序非递归    void _PosOrder_NotR(Node*root)    {        Node*cur = root;        if (cur == NULL)//空树        {            return;        }        stack<Node*>s;        while (!s.empty() || cur!=NULL)        {            //一直遍历右子树的最下面,边遍历边将节点压栈            while (cur)            {                s.push(cur);                cur=cur->_right;            }            if (!s.empty())            {                //右子树已经遍历完了,                cur = s.top();                s.pop();                cout << cur->_data << " ";                //遍历左子树                cur = cur->_left;            }        }        cout << endl;    }    //层序    void _LevelOeder(Node *root)    {        queue<Node *> q;        if (root == NULL)        {            return;        }        if (root)        {            q.push(root);//把根节点入队        }        while (!q.empty())        {            Node*front = q.front();            cout << front->_data << " ";            q.pop();            if (front->_left)                q.push(front->_left);//左子树入队            if (front->_right)                q.push(front->_right);//右子树入队        }        cout << endl;    }protected:    Node  *_root;};void TestBinaryTree(){    int a1[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };    size_t sz = sizeof(a1) / sizeof(a1[0]);    BinaryTree<int> t(a1, sz, '#');    BinaryTree<int> t1;    t1 = t;//调赋值运算符的重载    cout << t1.Size() << endl;    cout << t1.Depth() << endl;    cout << t1.LeftSize() << endl;    cout << t1.LeftSize() << endl;    t1.PrevOrder();    t1.InOrder();    t1.PosOrder();    t1.LevelOrder();    t1.PrevOrder_NotR();    t1.InOrder_NotR();    t1.PosOrder_NotR();}

.cpp文件

#include<iostream>#include"BinaryTree.h"using namespace std;int main(){    TestBinaryTree();    system("pause");    return 0;}

测试结果

0 0
原创粉丝点击