二叉树的应用

这篇博客介绍了如何使用非递归方法构建、遍历(前序、中序、后序)、统计(节点数量、高度、叶子节点数)和比较二叉树。代码实现包括栈结构和相关操作,涉及字符型二叉树节点的存储和处理。此外,还展示了如何检查两棵二叉树是否等价。
摘要由CSDN通过智能技术生成

可以实现的功能,把代码暂存在这里 

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <string.h>

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAXSIZE 100

typedef int Status;  //Status是函数的类型,其值是函数结果的状态代码

typedef char TElemType;
TElemType Nil = ' '; //字符型以空格符为空

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

typedef struct stack  //栈结构定义
{
    BiTree data[MAXSIZE];
    int tag[MAXSIZE];  //为栈中每个元素设置的标记,用于后序遍历
    int top;  //栈顶指针
}seqstack;

void Push(seqstack* s, BiTree t) //进栈
{
    s->data[s->top] = t;
    s->top++;
}

BiTree Pop(seqstack* s)  //出栈
{
    if (s->top != 0)
    {
        s->top--;
        return(s->data[s->top]);
    }
    else
        return NULL;
}

int IsKong(seqstack* s)
{
    if (s->top == 0)
        return 1;
    else
        return 0;
}

//用于构造二叉树
int treeIndex = 1;
typedef char String[24]; //0号单元存储串的长度
String str;

Status StrAssign(String T, char* chars)
{
    int i;
    if (strlen(chars) > MAXSIZE)
        return ERROR;
    else
    {
        T[0] = strlen(chars);
        for (i = 1; i < T[0]; i++)
        {
            T[i] = *(chars + i - 1);
        }
        return OK;
    }
}


Status Visit(TElemType e)
{
    printf("%c", e);
    return OK;
}

//构造空二叉树
Status InitBiTree(BiTree* T)
{
    *T = NULL;
    return OK;
}

//按前序输入二叉树中结点的值(一个字符)
//#表示空树,构造二叉链表表示二叉树T
void CreatBiTree(BiTree* T)
{
    TElemType ch;
    ch = str[treeIndex++];
    if (treeIndex > 24)
    {
        *T = NULL;
        return;
    }

    if (ch == '#')
        *T = NULL;
    else
    {
        *T = (BiTNode*)malloc(sizeof(BiTNode));
        if (!*T)
            exit(OVERFLOW);
        (*T)->data = ch;
        CreatBiTree(&(*T)->lchild);//构造左子树
        CreatBiTree(&(*T)->rchild);//构造右子树
    }
}

//二叉树存在的情况下非递归的遍历二叉树
//前序遍历
void PreOrderl(BiTree t)
{
    seqstack s;
    s.top = 0;
    while ((t) || (s.top != 0))  //当前处理的子树不为空或栈不为空则循环
    {
        if (t)
        {
            printf("%c", t->data);
            Push(&s, t);
            t = t->lchild;
        }
        else
        {
            t = Pop(&s);
            t = t->rchild;
        }
    }
}

//中序非递归遍历二叉树
void InOrderl(BiTree t)
{
    seqstack s;
    s.top = 0;
    while (t!=NULL || (s.top != 0))
    {
        if (t)
        {
            Push(&s, t);
            t = t->lchild;
        }
        else
        {
            t = Pop(&s);
            printf("%c", t->data);
            t = t->rchild;
        }
    }
}

//后序非递归遍历二叉树
void PostOrderl(BiTree t)
{
    seqstack s;
    s.top = 0;
    while ((t) || (s.top != 0))
    {
        if (t)
        {
            s.data[s.top] = t;
            s.tag[s.top] = 0;
            s.top++;
            t = t->lchild;
        }
        else
        {
            if (s.tag[s.top-1] == 1)
            {
                s.top--;
                t = s.data[s.top];
                printf("%c", t->data);
                t = NULL;
            }
            else
            {
                t = s.data[s.top - 1];
                s.tag[s.top - 1] = 1;
                t = t->rchild;
            }
        }
    }
}

//统计二叉树中节点的个数
int NumOfNode(BiTree t)
{
    if (t == NULL)
        return 0;
    else
        return(NumOfNode(t->lchild) + NumOfNode(t->rchild) + 1);
}

//非递归统计二叉树结点个数

int NumOfNodes(BiTree t)
{
    seqstack e;
    int count = 0;
    e.top = 0;
    while (1)
    {
        if (t)
        {
            Push(&e, t);
            count++;
            t = t->lchild;
        }
        else
        {
            t = Pop(&e);
            t = t->rchild;
            count++;
        }
        if (IsKong(&e))
            break;
    }
    return count;
}

//判断二叉树是否等价
int IsEqual(BiTree t1, BiTree t2)
{
    int t = 0;
    if (t1 == NULL && t2 == NULL)
        t = 1;
    else
        if (t1 != NULL && t2 != NULL)
            if (t1->data == t2->data)
                if (IsEqual(t1->lchild, t2->lchild))
                    t = IsEqual(t1->rchild, t2->rchild);
    return(t);
}

//求二叉树的高度(深度)
int Depth(BiTree t)
{
    int h, lh, rh;
    if (t == NULL)
        h = 0;
    else
    {
        lh = Depth(t->lchild);
        rh = Depth(t->rchild);
        if (lh >= rh)
            h = lh + 1;
        else
            h = rh + 1;
    }
    return h;
}

//在二叉树t中茶查找值为x的结点
BiTree Locate(BiTree t, TElemType x)
{
    BiTree p;
    if (t == NULL)
        return NULL;
    else
        if (t->data == x)
            return t;
        else
        {
            p = Locate(t->lchild, x);
            if (p)
                return p;
            else
                return Locate(t->rchild, x);
        }
}

//前序递归遍历二叉树
void PreOrderTraverse(BiTree T)
{
    if (T == NULL)
        return;
    printf("%c", T->data);
    PreOrderTraverse(T->lchild); 
    PreOrderTraverse(T->rchild); 
}

//递归实现求叶子节点个数
int get_leaf_number(BiTree t)
{
    if (t == NULL)
        return 0;
    if (t->lchild == NULL && t->rchild == NULL)
        return 1;

    return (get_leaf_number(t->lchild) + get_leaf_number(t->rchild));
}

//非递归的求叶子节点个数
/*非递归:本例采用先序遍历计算
判断当前访问的节点是不是叶子节点,然后对叶子节点求和即可。
 **/
int preorder_get_leaf_number(BiTree t)
{
    if (t == NULL)
        return 0;
    int num = 0;
    seqstack st;
    st.top = 0;
    while (t != NULL || !IsKong(&st))
    {
        while (t != NULL)
        {
            Push(&st,t);
            t = t->lchild;
        }

        if (!IsKong(&st))
        {
            t = Pop(&st);
            if (t->lchild == NULL && t->rchild == NULL)
                num++;
            t = t->rchild;
        }
    }

    return num;
}


int main()
{
    int i;
    BiTree T;
    InitBiTree(&T);
    
    char chars[] = "ABDH#K###E##CFI###G#J##";
    StrAssign(str, chars);
    CreatBiTree(&T);

    BiTree Y;  //创建一个和T相同的树
    InitBiTree(&Y);
    StrAssign(str, chars);
    treeIndex = 1;
    CreatBiTree(&Y);

    BiTree R;  //创建一个和T不同的树
    InitBiTree(&R);
    strcpy_s(chars, "ABDH#K###E##CFI###G#JV#");
    StrAssign(str, chars);
    treeIndex = 1;
    CreatBiTree(&R);

    printf("二叉树非递归前序遍历:\n");
    PreOrderl(T);
    printf("\n");
    printf("二叉树非递归中序遍历:\n");
    InOrderl(T);
    printf("\n");
    printf("二叉树非递归后序遍历:\n");
    PostOrderl(T);
    printf("\n");

    printf("二叉树递归前序遍历:\n");
    PreOrderTraverse(T);
    printf("\n");

    int a = NumOfNode(T)-1;
    printf("递归统计二叉树T的结点个数为%d\n", a);
    a = NumOfNodes(T)-1;
    printf("非递归统计二叉树T的结点个数为%d\n", a);

    a = Depth(T);
    printf("二叉树T的高度为%d\n", a);

    a = IsEqual(T,R);
    if (a == 0)
        printf("树T与R不等价\n");
    else
        printf("树T与R等价\n");

    a = IsEqual(T,Y);
    if (a == 0)
        printf("树T与Y不等价\n");
    else
        printf("树T与Y等价\n");

    printf("查找值为A的二叉树T的结点\n");
    BiTree p = Locate(T, 'A');
    if (p != NULL)
        printf("成功查找到该结点\n");
    else
        printf("该结点不存在!\n");
    printf("查找值为R的二叉树T的结点\n");
    p = Locate(T, 'R');
    if (p != NULL)
        printf("成功查找到该结点\n");
    else
        printf("该结点不存在!\n");

    a = preorder_get_leaf_number(T);
    printf("非递归统计二叉树T中的叶子节点个数为:%d\n", a);
    a = get_leaf_number(T);
    printf("递归统计二叉树T中的叶子节点个数为:%d\n", a);

    return 0;
}

存在的问题:创建二叉树时将设置的字符结束符号'/0'当成普通字符创建了二叉树结点,没有被视为结束符,二叉树创建的结束是根据for循环次数来解决的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值