二叉树的建造、递归与非递归遍历

来源:互联网 发布:php sqlsrv 编辑:程序博客网 时间:2024/06/05 13:32
#include "stdafx.h"#include <iostream>#include <stack>#include <queue>#include <Windows.h>using namespace std;typedef struct _Node{    int data;    struct _Node *left;    struct _Node *right;    bool isVisit;        //用于后序非递归遍历,表示节点是否可以访问    _Node()    {        data = 0;        left = NULL;        right = NULL;        isVisit = false;    }}Node, *PNode;//****************二叉树的递归建造********************//约定:输入0表示该节点的子树为NULLvoid RecurCreate(PNode pRoot){    int data;    cin>>data;    if (0 != data)    {        pRoot = new Node;        pRoot->data = data;        RecurCreate(pRoot->left);        RecurCreate(pRoot->right);    } }//假定二叉树如下图所示,利用前序和中序、后序与中序可以唯一确定一棵二叉树的原理//                       1//                     /   \//                    2     3//                  / \     / \//                 4   5   6   7 //               / \  ///              8   9 10const int MAX_NUM = 10;                             //二叉树的节点数int pre[MAX_NUM] = {1, 2, 4, 8, 9, 5, 10, 3, 6, 7}; //前序遍历的数组int mid[MAX_NUM] = {8, 4, 9, 2, 10, 5, 1, 6, 3, 7}; //中序遍历的数组int post[MAX_NUM] = {8, 9, 4, 10, 5, 2, 6, 7,3, 1}; //后序遍历的数组//获取前序数组的data在中序数组的索引int GetPositionInMid(int data){    for (int i = 0; i < MAX_NUM; i++)    {        if (mid[i] == data)        {            return i;        }    }}//利用前序和中序可以唯一确定一棵二叉树//参数说明// pRoot   —— 需要建造节点的指针引用// iPre    —— 表示pRoot节点的左子树(右子树)在前序数组的第一个索引// iMid    —— 表示pRoot节点的左子树(右子树)在中序数组的第一个索引// length  —— 表示pRoot节点的左子树(右子树)的长度void PreAndMidRecurCreate(PNode &pRoot, int iPre, int iMid, int length){    if (length <= 0)    {        return;    }    pRoot = new Node;    pRoot->data = pre[iPre];    int pos = GetPositionInMid(pre[iPre]);    PreAndMidRecurCreate(pRoot->left, iPre + 1, iMid, pos - iMid);    PreAndMidRecurCreate(pRoot->right, iPre + (pos - iMid) + 1, pos + 1, length - (pos - iMid) - 1);}//利用后序和中序可以唯一确定一棵二叉树//参数说明// pRoot   —— 需要建造节点的指针引用// iPost   —— 表示pRoot节点的左子树(右子树)在后序数组的第一个索引// iMid    —— 表示pRoot节点的左子树(右子树)在中序数组的第一个索引// length  —— 表示pRoot节点的左子树(右子树)的长度void PostAndMidRecurCreate(PNode &pRoot, int iPost, int iMid, int length){    if (length <= 0)    {        return;    }    pRoot = new Node;    pRoot->data = post[iPost];    int pos = GetPositionInMid(post[iPost]);    PostAndMidRecurCreate(pRoot->left, iPost - 1 - (length - (pos - iMid) - 1), iMid, pos - iMid);    PostAndMidRecurCreate(pRoot->right, iPost - 1, pos + 1, length - (pos - iMid) - 1);}//****************二叉树的递归遍历********************//前序递归遍历void PreRecurTraversal(PNode pRoot){    if (NULL != pRoot)    {        cout<<pRoot->data<<'\t';        PreRecurTraversal(pRoot->left);        PreRecurTraversal(pRoot->right);    }}//中序递归遍历void MidRecurTraversal(PNode pRoot){    if (NULL != pRoot)    {        MidRecurTraversal(pRoot->left);        cout<<pRoot->data<<'\t';        MidRecurTraversal(pRoot->right);    }}//序后递归遍历void PostRecurTraversal(PNode pRoot){    if (NULL != pRoot)    {        PostRecurTraversal(pRoot->left);        PostRecurTraversal(pRoot->right);        cout<<pRoot->data<<'\t';    }}//****************二叉树的非递归遍历********************//第一种前序非递归遍历void PreTraversalOne(PNode pRoot){    PNode pTree = pRoot;    stack<PNode> s;    while (!s.empty() || NULL != pTree)    {        while (NULL != pTree)        {            cout<<pTree->data<<'\t';            s.push(pTree);            pTree = pTree->left;        }        if (!s.empty())        {            pTree = s.top();            s.pop();            pTree = pTree->right;        }    }}//第二种前序非递归遍历void PreTraversalTwo(PNode pRoot){    PNode pTree = pRoot;    stack<PNode> s;    s.push(pTree);    while (!s.empty())    {        pTree = s.top();        cout<<pTree->data<<'\t';        s.pop();        if (NULL != pTree->right) //1、右子树进栈        {            s.push(pTree->right);        }        if (NULL != pTree->left) //2、左子树进栈        {            s.push(pTree->left);        }    }}//中序非递归遍历void MidTraversal(PNode pRoot){    PNode pTree = pRoot;    stack<PNode> s;    while (!s.empty() || NULL != pTree)    {        while (NULL != pTree)        {            s.push(pTree);            pTree = pTree->left;        }        if (!s.empty())        {            pTree = s.top();            cout<<pTree->data<<'\t';            s.pop();            pTree = pTree->right;        }    }}//后序非递归遍历void PostTraversal(PNode pRoot){    PNode pTree = pRoot;    stack<PNode> s;    while (!s.empty() || NULL != pTree)    {        while (NULL != pTree)        {            s.push(pTree);            pTree = pTree->left;        }        if (!s.empty())        {            pTree = s.top();            if (pTree->isVisit)            {                cout<<pTree->data<<'\t';                s.pop();                pTree = NULL;            }            else            {                pTree->isVisit = true;                pTree = pTree->right;            }        }    }}//层序非递归遍历——用队列,注意与第二种非递归前序遍历的区别void LevelTraversal(PNode pRoot){    PNode pTree = pRoot;    queue<PNode> q;    q.push(pTree);    while (!q.empty())    {        pTree = q.front();        q.pop();        cout<<pTree->data<<'\t';        if (NULL != pTree->left)  //1、左子树进队列        {            q.push(pTree->left);        }        if (NULL != pTree->right) //2、右子树进队列        {            q.push(pTree->right);        }    }}//辅助函数,设置控制台的颜色void SetConsoleTextColor(WORD dwColor){    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);    if (INVALID_HANDLE_VALUE == handle)    {        return;    }    SetConsoleTextAttribute(handle, dwColor);}int _tmain(int argc, _TCHAR* argv[]){    PNode pRoot1 = NULL;    PNode pRoot2 = NULL;    cout<<endl<<"******************根据前序和中序建造二叉树********************"<<endl<<endl;    PreAndMidRecurCreate(pRoot1, 0, 0, MAX_NUM);        SetConsoleTextColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);    cout<<endl<<"******************层序遍历二叉树********************"<<endl<<endl;    LevelTraversal(pRoot1);    SetConsoleTextColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);    cout<<endl<<"******************递归遍历二叉树********************"<<endl<<endl;    cout<<endl<<"       **********前序递归遍历二叉树**********"<<endl<<endl;    PreRecurTraversal(pRoot1);    cout<<endl<<"       **********中序递归遍历二叉树**********"<<endl<<endl;    MidRecurTraversal(pRoot1);    cout<<endl<<"       **********后序递归遍历二叉树**********"<<endl<<endl;    PostRecurTraversal(pRoot1);    SetConsoleTextColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);    cout<<endl<<"******************根据后序和中序建造二叉树********************"<<endl<<endl;    PostAndMidRecurCreate(pRoot2, MAX_NUM - 1, 0, MAX_NUM);    SetConsoleTextColor(FOREGROUND_GREEN | FOREGROUND_INTENSITY);    cout<<endl<<"******************非递归遍历二叉树********************"<<endl<<endl;    cout<<endl<<"       **********前序非递归遍历二叉树**********"<<endl<<endl;    PreTraversalOne(pRoot2);    cout<<endl;    PreTraversalTwo(pRoot2);    cout<<endl<<"       **********中序非递归遍历二叉树**********"<<endl<<endl;    MidTraversal(pRoot2);    cout<<endl<<"       **********后序非递归遍历二叉树**********"<<endl<<endl;    PostTraversal(pRoot2);    return 0;}
复制代码

输出效果如图所示

0 0
原创粉丝点击