二叉树

/*测试数据 ABD#G###CE##F##*/

#include <iostream>
#include <stdlib.h>
using namespace std;
typedef struct node
{
    char data;
    struct node* lchild;
    struct node* rchild;
}*bitree,bitnode;
typedef struct qstack
{
    bitree  *base;//存储bitree指针的数组,所以类型是bitree,因为存储的是一级指针的地址,所以该指针数组为二级指针数组
    int top;
    int size;
}qstack;
void init(qstack &s)
{
    s.base=(bitree*)malloc(100*sizeof(bitree));
    s.top=0;
}
bool empty(qstack  &s)
{
    if(s.top==0)
        return true;
    else
        return false;
}
void push(qstack &s,bitree e)//注意入栈的时候,是e指针的地址
{
    s.base[s.top]=e;
    s.top++;
}
void pop(qstack &s)
{
    s.top--;
}
bitree gettop(qstack &s)//返回栈顶元素也应该是bitree即返回指针
{
    return s.base[s.top-1];
}
void traverse(qstack &s)
{
    int i;
    for(i=0;i<s.top;i++)
    {
        cout<<s.base[i];
    }
}
void create(bitree &bt)//先序次序创建二叉树所以只能先序输入
{
    char data;
    cin>>data;
    if(data == '#')
    {
        bt=NULL;
    }
    else
    {
        bt=(bitree)malloc(sizeof(bitnode));//bt指向一个空间
        bt->data=data;
        create(bt->lchild);
        create(bt->rchild);
    }
}

void pretraverse(bitree bt)//先序遍历递归版
{
    if(bt!=NULL)
    {
        cout<<bt->data;
        pretraverse(bt->lchild);
        pretraverse(bt->rchild);
    }
}

void ontraverse(bitree bt)//中序遍历递归版
{
    if(bt!=NULL)
    {
        ontraverse(bt->lchild);
        cout<<bt->data;
        ontraverse(bt->rchild);
    }
}

void postraverse(bitree bt)//后序遍历递归版
{
    if(bt!=NULL)  //记住要加上这个判断语句,因为如果是左孩子活右孩子为空,则不能输出data
    {
        postraverse(bt->lchild);
        postraverse(bt->rchild);
        cout<<bt->data;
    }
}

void pretraverse_(bitree bt)//先序遍历非递归版
{
    bitree &p=bt;
    qstack s;
    init(s);
    while(!empty(s) || p!=NULL)
    {
        while(p!=NULL)
        {
            cout<<p->data;
            push(s,p);
            p=p->lchild;
        }
        if(!empty(s))
        {
            p=gettop(s);
            pop(s);
            p=p->rchild;
        }
    }
}

void ontraverse_(bitree bt)//中序遍历非递归版
{
    bitree &p=bt;
    qstack s;
    init(s);
    while(!empty(s) || p!=NULL)
    {
        while(p!=NULL)
        {
            push(s,p);//结点入栈
            p=p->lchild;//一直往左孩子方向进行直到没有左孩子的时候跳出
        }
        if(!empty(s))
        {
            p=gettop(s);//如果不加上这个,当p从上一个while跳出时为空,不能输出data
            cout<<p->data;//如果是左孩子则输出,左孩子出栈,左孩子的右孩子是空,p变成根结点
            pop(s);
            p=p->rchild;
        }
    }
}

void postraverse_(bitree bt)//后序非递归遍历
{
    char k;
    qstack s;
    init(s);
    bitree cur;
    bitree pre=NULL;
    push(s,bt);
    while(!empty(s))
    {
        cur=gettop(s);
        if(((cur->lchild == NULL) && (cur->rchild == NULL)) || (pre!=NULL && ((pre==(cur->lchild) || pre==(cur->rchild)))))
        {
            k=cur->data;
            cout<<cur->data;
            pop(s);
            pre=cur;
        }
        else
        {
            if(cur->rchild!=NULL)//此处应该注意,先是右孩子入栈,然后才是左孩子,因为后序遍历的最开始是左孩子,所以应该往左孩子的方向进行判断
                push(s,cur->rchild);//但是如果先放入左孩子入栈,在放入右孩子入栈,则取栈顶的时候,是右孩子,然后方向就变成了向右孩子的方向所以
            if(cur->lchild!=NULL)//应该右孩子先入栈左孩子后入栈
                push(s,cur->lchild);
        }
    }
}

int countleaf(bitree bt)//子叶子结点的统计
{
    int countleft,countright;
    if(bt==NULL)//如果是空树则返回0
        return 0;
    else if((bt->rchild==NULL) && (bt->rchild==NULL))//如果只有根结点做叶子结点返回1
        return 1;
    countleft=countleaf(bt->lchild);//求左树的叶子结点
    countright=countleaf(bt->rchild);//求右树的叶子结点
    return countleft+countright;
}

int deep(bitree bt)//求树的深度
{
    int depleft,depright;
    if(bt==NULL)
        return 0;
    depleft=deep(bt->lchild);
    depright=deep(bt->rchild);
    if(depleft>=depright)return depleft+1;
    else
        return depright+1;
    
}

bitree find(bitree &bt,char e)//寻找某个字符在不在树中
{
    bitree p;
    if(bt==NULL)
        return NULL;
    if(bt->data==e)
        return bt;
    p=find(bt->lchild,e);
    if(p!=NULL && p->data==e)//这里需要加上p!=NULL因为当不是空树,但是一个根结点的左子树或右子树为空的时候返回的是NULL,NULL没有data
        return p;
    p=find(bt->rchild,e);
    if(p!=NULL &&p->data==e)
        return p;
    return NULL;
}

bitree findleft(bitree &bt,char e)//寻找左孩子
{
    bitree p;
    p=find(bt,e);
    if(p->lchild!=NULL)
        return p->lchild;
    else
        return NULL;
}

bitree findright(bitree &bt,char e)//寻找右孩子
{
    bitree p;
    p=find(bt,e);
    if(p->rchild!=NULL)
        return p->rchild;
    else
        return NULL;
}

void insert(bitree bt,char e,int flag,bitree T)//插入左子树或右子树 bt被插入的树 e为bt中被插入的点 flag为0插入左树为1插入右树  T为插入的树
{
    bitree p;
    p=find(bt,e);//寻找到要插入的结点
    if(flag==0)
        p->lchild=T;
    if(flag==1)
        p->rchild=T;
}

void delete_(bitree bt,char e,int flag)//删除左或右树 bt被删除的树 e为删除的点 flag为0删除左树 为1删除右树
{
    bitree p;
    p=find(bt,e);
    if(flag==0)
        p->lchild=NULL;
    if(flag==1)
        p->rchild=NULL;
}

bitree findlast(bitree bt,char e)
{
    bitree p;
    if(bt==NULL)
        return NULL;
    if(bt->data==e)
        return NULL;
    p=findlast(bt->lchild,e);
    if(p!=NULL && (p->lchild->data == e|| p->rchild->data == e))
        return p;
    p=findlast(bt->rchild,e);
    if(p!=NULL && (p->lchild->data == e|| p->rchild->data == e))
        return p;
    return NULL;
}
//bitree family(bitree bt,char e)
//{
//    if(bt->data==e)
//        return NULL;
//    else
//       
//        
//}

void destroy(bitree bt)//摧毁二叉树
{
    if(bt==NULL)
        return ;
    destroy(bt->lchild);
    destroy(bt->rchild);
    free(bt);
}

int main()
{
    bitree bt,p;
    create(bt);
    p=findlast(bt,'E');
    cout<<p->lchild->data;
//    p=findright(bt,'B');
//    if(p!=NULL)
//        cout<<p->data;
//    else
//        cout<<"无右孩子";//无左孩子
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值