数据结构————二叉树

二叉树是数据结构的一个重要内容之一,那么对于我们这些学习编程的人来说,掌握二叉树的各种遍历(递归遍历和非递归遍历)是必不可少的,下面我们就分析一下,二叉树的各种遍历方法:
1首先得建立一个二叉树:
1.二叉树节点
struct BinaryTreeNode//二叉树节点 
{ 
    BinaryTreeNode* _left; 
    BinaryTreeNode* _right; 
    T _data; 
    BinaryTreeNode(const T data)
        :_left(NULL)//二叉树左孩子
        ,_right(NULL)//右孩子
        ,_data(data)
    {
    }
}; 
2.造二叉树
BinaryTree(const T* a, size_t size, const T& invalid)//二叉树构造函数
            :_root(NULL)
        {
            size_t index=0;
            _root=CreatBinaryTree(a,size,index,invalid);
        }
Node* CreatBinaryTree(const T* a,size_t size,size_t& index,const T& invalid)//制造二叉树(前序)
    {
        Node* root=NULL;
        if(a[index]!=invalid&&index<size)
        {
            root=new Node(a[index]);//new一个根节点,先造根节点
            root->_left=CreatBinaryTree(a,size,++index,invalid);//再造左节点
            root->_right=CreatBinaryTree(a,size,++index,invalid);//再造右节点
        }
        return root;
    }   
3.遍历二叉树(递归)
①前序遍历,前序遍历是1.遍历根节点、2.遍历左节点、3.遍历有节点
void PrevOrder()//前序遍历
    {
        _PrevOrder(_root);//传根节点
        cout<<endl;
    }
    void _PrevOrder(Node* T)
    {
        if(T==NULL)
            return;
        else
        {
            cout<<T->_data<<" ";//先访问根节点,在这里是直接输出
            _PrevOrder(T->_left);//访问左节点
            _PrevOrder(T->_right);//访问有节点
        }
    }
②中序遍历(递归),中序遍历和前序遍历类似,只不过是将访问顺序变为1.左节点、2.根节点、3.有节点
void InOrder()
    {
        _InOrder(_root);
        cout<<endl;
    }
    void _InOrder(Node* T)
    {
        if(T==NULL)
            return;
        else
        {
            _InOrder(T->_left);
            cout<<T->_data<<" ";
            _InOrder(T->_right);
        }
    }
    void PostOrder()
    {
        _PostOrder(_root);
        cout<<endl;
    }
③后序遍历,也不例外,1.访问左节点、2.访问右节点、3.访问根节点
void PostOrder()
    {
        _PostOrder(_root);
        cout<<endl;
    }
void _PostOrder(Node* T)
    {
        if(T==NULL)
            return;
        else
        {
            _PostOrder(T->_left);//访问左节点
            _PostOrder(T->_right);//访问右节点
            cout<<T->_data<<" ";//访问根节点
        }
    }
4.非递归遍历二叉树
①前序序访问二叉树

这里写图片描述

前序采用栈来处理,如图所示,先压1,然后出1,压 2,3,这里先压3,后压2,是栈的特点,后进先出所以先出2,压 5、 4;然后出4,压9、 8;出 8,然后出9、出 5、出3;压 7 、6,出7,出6;

得到1,2,4,8,9,5,3,7,6;

void PrevOrder_NonR()
    {
        Node* T = _root;
        stack<Node*> s;
        while(T!=NULL||!s.empty())
        {
            if(T!=NULL)
            {
                cout<<T->_data<<" ";
                s.push(T);
                T=T->_left;
            }
            else
            {   T=s.top();
                s.pop();
                T=T->_right;
            }
        }
        cout<<endl;
    }
②中序遍历
中序遍历和前序是一样的采用栈来处理,只不过是先访问左节点,然后根节点、右节点
void InOrder_NonR()
    {
        Node* T = _root;
        stack<Node*> s;
        if(T==NULL)
            return;
        else
        {
            Node* temp=T;
            while(!s.empty()||temp!=NULL)   
            {
                if(temp!=NULL)
                {
                    s.push(temp);//先将所有的走节点压进去
                    temp=temp->_left;
                }
                else
                {
                    temp=s.top();//访问节点
                    cout<<temp->_data<<" ";//记录
                    s.pop();//出栈
                    temp=temp->_right;//判断有节点;
                }
            }
            cout<<endl;
        }
    }
③后序访问
后序访问就比较复杂了,我解决他的办法是采用俩个栈,首先要说明的是:后序和前序是有关系的,来对比一下,前序:1.根节点、2.左节点、3.右节点后续:1.左节点、2、右节点、3.根节点。那么我们可以采用类似的方法:处理先以1.根节点、2.右节点、3.左节点 这种方式遍历并将遍历结果压入output栈中,然后出栈退栈,既得到1.左节点、2.右节点、3.根节点。
void PostOrder_NonR()
    {
        Node* T = _root;
        stack<Node*> s,output;
        while(T!=NULL||!s.empty())
        {
            if(T!=NULL)
            {
                s.push(T);//先根节点
                output.push(T);//入栈
                T=T->_right;//右节点
            }
            else
            {   
                T=s.top();
                s.pop();
                T=T->_left;//走左节点
            }
        }
        while(output.size()!=0)
        {
            Node* temp = output.top();
            cout<<temp->_data<<" ";
            output.pop();
        }
        cout<<endl;
    }
④层序访问二叉树
#下图是层序访问的结构图

这里写图片描述
这里写图片描述

有上述结构图可以看出这种访问方式,与队列是一模一样的,所以我们采用队列的方式解决。1.现将1入队,先记录1 然后出队(访问),通过1来使得2、3入队;然后2,记录后2出队,4 、5入队;然后3,记录后出队,6 、7入队….,就这样一直走下去直到队列为空为止。
void LevelOrder()
    {
        Node* root = _root;
        queue<Node*> q;
        if(root)
            q.push(root);//先使得第一个节点入队
        while(q.size()!=0)
        {
            Node* temp=q.front();//记录
            q.pop();//出队
            cout<<temp->_data<<" ";
            if(temp->_left!=NULL)//先左
                q.push(temp->_left);
            if(temp->_right!=NULL)//后右
                q.push(temp->_right);
        }
        cout<<endl;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值