C++学习---二叉树的输入及非递归遍历

二叉树的二叉链表存储表示如下

//二叉树的二叉链表存储表示
typedef struct BiTNode {
    char data;//结点数据域
    struct BiTNode* lchild, * rchild;//左右孩子指针
}*BiTree;

根据括号表示法的字符串创建树(括号里的表示括号前结点的子结点,‘,’号左边是左子结点,右边是右子结点)

比如:a(b(d,e),c(f,g(h,i)))

表示的则是

 

  

//创建树
void CreateBiTree(BiTree& T)
{
    stack<BiTNode*> s;//用于确定需要操作的结点
    BiTNode* p=NULL;
    int i = 0;
    bool child_Direct;//0表示左子结点,1表示右子结点
    //按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
    string TreeStr;
    cin >> TreeStr;
    while (TreeStr[i] != '\0') {
        switch (TreeStr[i])
        {
        case'('://左子结点
            s.push(p);
            child_Direct = false;
            break;
        case')':
            s.pop();
        case','://右子结点
            child_Direct = true;
            break;

        default:
            p = new BiTNode;
            p->data = TreeStr[i];
            p->lchild = p->rchild = NULL;
            if (T == NULL)//若根节点为空则p指向根节点
                T = p;
            else {
                if (!child_Direct)
                    s.top()->lchild = p;
                else
                    s.top()->rchild = p;
            }
            break;
        }
        i++;
    }

}

  

 非递归先序、中序、后序遍历

先序:

void PreOrderTraverse(BiTree T) {
    stack<BiTNode*> s;
    BiTNode* p = T, * q = new BiTNode();
    while (p != NULL || !s.empty()) {
        if (p)//p非空
        {
            cout << p->data;
            s.push(p);//根指针入栈
            p = p->lchild;//遍历左子树
        }
        else {
            p = s.top();
            s.pop();
            p = p->rchild;//遍历右子树
        }
    }
}

  

中序:

//中序遍历
void InOrderTraverse(BiTree T) {
    stack<BiTNode*> s;
    BiTNode* p = T, * q = new BiTNode();
    while (p != NULL || !s.empty()) {
        if (p)//p非空
        {
            s.push(p);//根指针入栈
            p = p->lchild;//遍历左子树
        }
        else {
            p = s.top();
            s.pop();
            cout << p->data;
            p = p->rchild;//遍历右子树
        }
    }
}

  

后序:

//后序遍历
void PostOrderTraverse(BiTree T) {
    BiTNode* p = T, * r = NULL;
    stack<BiTNode*> s;
    while (p != NULL || !s.empty()) {
        if (p != NULL) {//走到最左边
            s.push(p);
            p = p->lchild;
        }
        else {
            p = s.top();
            if (p->rchild != NULL && p->rchild != r)//右子树存在,未被访问
                p = p->rchild;
            else {
                s.pop();
                cout << p->data;
                r = p;//记录最近访问过的节点
                p = NULL;//节点访问完后,重置p指针
            }
        }//else
    }//while
    
}

完整代码

#include <iostream>
#include <stack>
#include <string>
using namespace std;

//二叉树的二叉链表存储表示
typedef struct BiTNode {
    char data;//结点数据域
    struct BiTNode* lchild, * rchild;//左右孩子指针
}*BiTree;

void Initial(BiTree& T) {
    T = new BiTNode;
    T = NULL;
}
//创建树
void CreateBiTree(BiTree& T)
{
    stack<BiTNode*> s;//用于确定需要操作的结点
    BiTNode* p=NULL;
    int i = 0;
    bool child_Direct;//0表示左子结点,1表示右子结点
    //按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
    string TreeStr;
    cin >> TreeStr;
    while (TreeStr[i] != '\0') {
        switch (TreeStr[i])
        {
        case'('://左子结点
            s.push(p);
            child_Direct = false;
            break;
        case')':
            s.pop();
        case','://右子结点
            child_Direct = true;
            break;

        default:
            p = new BiTNode;
            p->data = TreeStr[i];
            p->lchild = p->rchild = NULL;
            if (T == NULL)//若根节点为空则p指向根节点
                T = p;
            else {
                if (!child_Direct)
                    s.top()->lchild = p;
                else
                    s.top()->rchild = p;
            }
            break;
        }
        i++;
    }

}
//以括号表示法输出二叉树
void DispBTNode(BiTNode *&b)  
{
    if (b != NULL)
    {
        cout<<b->data;
        if (b->lchild != NULL || b->rchild != NULL)
        {
            cout<<"(";
            DispBTNode(b->lchild);
            if (b->rchild != NULL) cout<<(",");
            DispBTNode(b->rchild);
            cout<<")";
        }
    }
}

#pragma region 递归遍历
//先序
void PreOrderTraverseR(BiTree T) {
    if (T != NULL) {
        cout << T->data;
        PreOrderTraverseR(T->lchild);
        PreOrderTraverseR(T->rchild);
    }
}
//中序
void InOrderTraverseR(BiTree T) {
    if (T != NULL) {
        InOrderTraverseR(T->lchild);
        cout << T->data;
        InOrderTraverseR(T->rchild);
    }
}
//后序
void PostOrderTraverseR(BiTree T) {
    if (T != NULL) {
        PostOrderTraverseR(T->lchild);
        PostOrderTraverseR(T->rchild);
        cout << T->data;
    }
}
#pragma endregion


#pragma region 非递归遍历
//先序遍历
void PreOrderTraverse(BiTree T) {
    stack<BiTNode*> s;
    BiTNode* p = T, * q = new BiTNode();
    while (p != NULL || !s.empty()) {
        if (p)//p非空
        {
            cout << p->data;
            s.push(p);//根指针入栈
            p = p->lchild;//遍历左子树
        }
        else {
            p = s.top();
            s.pop();
            p = p->rchild;//遍历右子树
        }
    }
}
//中序遍历
void InOrderTraverse(BiTree T) {
    stack<BiTNode*> s;
    BiTNode* p = T, * q = new BiTNode();
    while (p != NULL || !s.empty()) {
        if (p)//p非空
        {
            s.push(p);//根指针入栈
            p = p->lchild;//遍历左子树
        }
        else {
            p = s.top();
            s.pop();
            cout << p->data;
            p = p->rchild;//遍历右子树
        }
    }
}
//后序遍历
void PostOrderTraverse(BiTree T) {
    BiTNode* p = T, * r = NULL;
    stack<BiTNode*> s;
    while (p != NULL || !s.empty()) {
        if (p != NULL) {//走到最左边
            s.push(p);
            p = p->lchild;
        }
        else {
            p = s.top();
            if (p->rchild != NULL && p->rchild != r)//右子树存在,未被访问
                p = p->rchild;
            else {
                s.pop();
                cout << p->data;
                r = p;//记录最近访问过的节点
                p = NULL;//节点访问完后,重置p指针
            }
        }//else
    }//while
    
}
#pragma endregion
int main()
{
    BiTree b;
    Initial(b);
    //创建树
    CreateBiTree(b);
    //先序遍历
    cout << "先序遍历:";
    PreOrderTraverse(b);
    cout << endl;
    //中序遍历
    cout << "中序遍历:";
    InOrderTraverse(b);
    cout << endl;
    //后序遍历
    cout << "后序遍历:";
    PostOrderTraverse(b);
}

  

程序示例:

 

posted @ 2020-10-21 23:21  edl李曉宇  阅读(1367)  评论(0编辑  收藏  举报