树的建立 遍历

 

二叉树是采用递归定义的,实现起来代码简洁(也许并不简单)。并且它在具体的计算机科学中有很重要的运用,是一种很重要的数据结构,二叉树有三种遍历和建立的方式。今天先学习一下它的建立和打印。

建立:

#include<cstdio>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;

typedef struct BiTNode{
    char data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

BiTree CreateBiTree(){
    char ch;
    BiTree T;
    scanf("%c",&ch);
    if(ch=='#')T=NULL;
    else{
        T = (BiTree)malloc(sizeof(BiTNode));
        T->data = ch;
        T->lchild = CreateBiTree();
        T->rchild = CreateBiTree();
}

二叉树遍历算法

1. 前序/中序/后序遍历(递归实现)

// 前序遍历
void BT_PreOrder(BiTreePtr pNode)
{
    if (!pNode)  return;
     
    visit(pNode);
    BT_PreOrder(pNode->left);
    BT_PreOrder(pNode->right);  
}
// 中序遍历
void BT_PreOrder(BiTreePtr pNode)
{
    if (!pNode)  return;
     
    BT_PreOrder(pNode->left);
    visit(pNode);
    BT_PreOrder(pNode->right);
}
// 后序遍历
void BT_PreOrder(BiTreePtr pNode)
{
    if (!pNode)  return;
     
    BT_PreOrder(pNode->left);
    BT_PreOrder(pNode->right);
    visit(pNode);
}

2. 前序遍历(非递归实现)



// 用栈实现
void BT_PreOrderNoRec1(BiTreePtr pNode)
{
    stack<BiTreePtr> s;
    while (!pNode || !s.empty())
    {
        if (!pNode)
        {
            visit(pNode);
            s.push(pNode);
            pNode = pNode->left;
        }
        else
        {
            pNode = s.pop();
            pNode = pNode->right;
        }
    }
}
 
// 用栈实现
void BT_PreOrderNoRec2(BiTreePtr pNode)
{
    if (!pNode)
    {
        stack<BiTreePtr> s;
        s.push(pNode);
        while (!s.empty())
        {
            BiTreePtr pvNode = s.pop();
            visit(pvNode);
            s.push(pvNode->right);
            s.push(pvNode->left);
        }
    }
}
 
// 不用栈实现 每个节点含父节点指针和isVisited【默认为false】状态变量 且该二叉树含一个头节点
void BT_PreOrderNoRec3(BiTreePtr pNode)
{
    while (!pNode)// 回溯到指向根节点的头节点时退出
    {
        if( !pNode->bVisited )//判定是否已被访问
        {  
            visit(pNode);
            pNode->isVisited = true;
        }
        if ( pNode->left && !pNode->left->isVisited )
            pNode = pNode->left;
        else if( pNode->right && !pNode->right->isVisited )
            pNode = pNode->right;
        else   //回溯
            pNode = pNode->parent;
    }
}

3. 中序遍历(非递归实现)


// 用栈实现
void BT_InOrderNoRec1(BiTreePtr pNode)
{
    stack<BiTreePtr> s;
    while (!pNode || !s.empty())
    {
        if (!pNode)
        {
            s.push(pNode);
            pNode = pNode->left;
        }
        else
        {
            pNode = s.pop();
            visit(pNode);
            pNode = pNode->right;
        }
    }
}
// 不用栈实现 每个节点含父节点指针和isVisited【默认为false】的状态变量 且该二叉树含一个头节点
void BT_InOrderNoRec2(BiTreePtr pNode)
{
    while (!pNode) // 回溯到指向根节点的头节点时退出
    {
        while (pNode->left && !pNode->left->isVisited)
            pNode = pNode->left;
        if (!pNode->isVisited)
        {
            visit(pNode);
            pNode->isVisited=true;
        }
        if (pNode->right && !pNode->right->isVisited)
            pNode = pNode->right;
        else
            pNode = pNode->parent;
    }
}

4. 后序遍历(非递归实现)


void BT_PostOrderNoRec(BiTreePtr pNode)
{
    if(!pNode) return;
 
    stack<BiTreePtr> s;
    s.push(pNode);
 
    while (!s.empty())
    {
        BiTreePtr pvNode = s.pop();
        if (pvNode->isPushed)// 表示其左右子树都已入栈,访问该节点
            visit(pvNode);
        else
        {
            if (pvNode->right)
            {
                pvNode->right->isPushed = false;
                S.push(pvNode->right);
            }
            if (pvNode->left)
            {
                pvNode->left->isPushed = false;
                s.push(pvNode->left);
            }
            pvNode->isPushed = true;
            s.push(pvNode);
        }
    }
}

5. 层序遍历(使用队列)


void BT_LevelOrder(BiTreePtr pNode)
{
    if (!pNode) return;
 
    queue<BiTreePtr> q;
    q.push(pNode);
 
    BiTreePtr pvNode;
    while (!q.empty())
    {
        pvNode = q.pop();
        visit(pvNode);
 
        if (pvNode->left)
            q.push(pvNode->left);   
        if (pvNode->right)
            q.push(pvNode->right);           
    }
}

..........

#include<bits/stdc++.h>
using namespace std;
char s[105];
typedef struct BiTNode
{
    char data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

int CreateBiTree(BiTree &T,int &index,int &n)
{
    if(index==n)return 0;
    if(s[index]=='#')
    {
        T=NULL;
        index++;
    }
    else
    {
        T=(BiTree)malloc(sizeof(BiTNode));
        T->data=s[index];
        index++;
        CreateBiTree(T->lchild,index,n);
        CreateBiTree(T->rchild,index,n);
    }
    return 0;
}

void Visit(BiTree T)
{
    if(T->data!='#')
    printf("%c",T->data);
}
void PostOrder(BiTree T)
{
    if(T!=NULL)
    {
        PostOrder(T->lchild);
        PostOrder(T->rchild);
        Visit(T);
    }
}
int main()
{
    while(~scanf("%s",s))
    {
        BiTree T;
        int len=strlen(s);
        int index=0;
        CreateBiTree(T,index,len);
        PostOrder(T);
        printf("\n");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值