二叉树的基本操作

二叉树的基本操作很烦,一个搞不好脑袋就炸了,二叉树最重要的操作就是遍历,而二叉树的操作都是基于遍历实现的,(比如:求叶子节点的个数、求二叉树的深度、求节点的总个数)而遍历最常用的方法就是递归

工欲善其事必先利其器
首先把变量定义好

#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 10000
#define STACK_SIZE 100
#define OK 1
#define ERROR -1
typedef char ElemType;//二叉树中值的类型,可以根据需要更改
typedef int Status;

定义二叉树的结构体

typedef struct BTNode
{
    ElemType data;
    struct BTNode *Lchild, *Rchild;
}BTNode;

栈的结构体

typedef struct SqStack
{
    int top;
    int bottom;
    BTNode array[STACK_SIZE];
    int stacksize;/*当前已分配空间,以元素为单位*/

}SqStack;

初始化栈

Status Init_Stack(SqStack *S)
{
    if(!S->bottom)
    {
        printf("initialize fail\n");
        exit(-1);
    }
    S->top = S->bottom = 0;
    S->stacksize = STACK_SIZE;
    return OK;
}

入栈

Status Push(SqStack *S, BTNode *B)
{
    if (S->top - S->bottom == STACK_SIZE - 1)//栈满
    {
        return ERROR;
    }

    S->array[S->top] = *B;
    S->top++;

    return OK;
}

弹出栈顶元素

BTNode Pop(SqStack *S)
{
    BTNode B;
    if (S->bottom == S->top)
    {
        printf("This stack is empty!\n\n");
        exit(0);
    }
    else
    {
        B = S->array[(S->top) - 1];
        S->top--;
    }
    return B;
}

二叉树的初始化(初始化一棵空二叉树)

Status Init_BTNode(BTNode *T)
{
    T->Lchild = NULL;
    T->Rchild = NULL;
    T->data = '\0';

    return OK;
}

创建一颗二叉树

Status Create_BTNode(BTNode *T)
{
    char ch;//树根的值
    BTNode *L;//左子树
    BTNode *R;//右子树
    char lc;//是否有左子树判断符
    char rc;//是否有右子树判断符

    L = (BTNode *)malloc(sizeof(BTNode));
    R = (BTNode *)malloc(sizeof(BTNode));

    T->Lchild = L;
    T->Rchild = R;

    printf("data:\n");
    fflush(stdin);//从控制台读取字符类型  保证不出现异常
    scanf("%c", &ch);

    if(ch == ' ')//空树
    {
        T->Lchild = NULL;
        T->Rchild = NULL;
    }
    else
    {
        T->data = ch;

        printf("Does %c has left child?(Y|N)\n", T->data);
        fflush(stdin);
        scanf("%c", &lc);
        while(lc != 'Y' && lc != 'y' && lc != 'N' && lc != 'n')
        {
            printf("error!\t please enter again\n");
            fflush(stdin);
            scanf("%c", &lc);
        }

        if(lc == 'y' || lc == 'Y')
        {
            Create_BTNode(L);
        }
        else
        {
            T->Lchild = NULL;
            free(L);
        }

        printf("Does %c has right child?(Y|N)\n", T->data);
        fflush(stdin);
        scanf("%c", &rc);
        while(rc != 'Y' && rc != 'y' && rc != 'N' && rc != 'n')
        {
            printf("error!\t please enter again\n");
            fflush(stdin);
            scanf("%c", &rc);
        }
        if(rc == 'Y' || rc == 'y')
        {
            Create_BTNode(R);
        }
        else
        {
            T->Rchild = NULL;
            free(R);
        }
    }

    return OK;
}

遍历二叉树

//先序遍历(递归)
Status PreOrderTraverse(BTNode *T)
{
    if(T != NULL)
    {
        printf("%c", T->data);
        PreOrderTraverse(T->Lchild);
        PreOrderTraverse(T->Rchild);
    }
    return OK;
}
//中序遍历(递归)
Status InOrderTraverse(BTNode *T)
{
    if(T != NULL)
    {
        InOrderTraverse(T->Lchild);
        printf("%c", T->data);
        InOrderTraverse(T->Rchild);
    }
    return OK;
}

//后序遍历(递归)
Status PosOrderTraverse(BTNode *T)
{
    if(T != NULL)
    {
        PosOrderTraverse(T->Lchild);
        PosOrderTraverse(T->Rchild);
        printf("%c", T->data);
    }
    return OK;
}

求二叉树的节点总个数

Status child(BTNode *T)
{
    int Lchildnumber = 0;
    int Rchildnumber = 0;

    if(T->Lchild != NULL)
        Lchildnumber = child(T->Lchild);
    if(T->Rchild != NULL)
        Rchildnumber = child(T->Rchild);
    return Lchildnumber + Rchildnumber + 1;//返回每个节点的左右节点加上本身
}

求叶子结点个数

int leafchild(BTNode *T)
{
    int Lleafchild = 0;
    int Rleafchild = 0;

    if(T->Lchild != NULL)
        Lleafchild = leafchild(T->Lchild);
    if(T->Rchild != NULL)
        Rleafchild = leafchild(T->Rchild);
    if(T->Lchild == NULL && T->Rchild == NULL)
        return 1;
    else
        return Lleafchild + Rleafchild;
}

求二叉树的深度

int depth(BTNode *T)
{
    int Rdepth = 0;
    int Ldepth = 0;

    if(T->Lchild != NULL)
        Ldepth = depth(T->Lchild);
    if(T->Rchild != NULL)
        Rdepth = depth(T->Rchild);

    return(Rdepth > Ldepth) ? Rdepth + 1 : Ldepth + 1;//返回每个节点的左、右长度较大的一个加一
}

主方法

int main()
{
    int a;
    int flag = 0;//初始化的标志位
    int tag = 0;//建立二叉树的标志位
    BTNode T;

    printf("1.initializeBTNode\n2.createBTNode\n3.travelBTNode\n4.child number\n5.BiTreeDepth\n6.leaf child\n");
    printf("hello\n");
    while(1)
    {
        printf("please enter operation code:");
        scanf("%d", &a);

        switch(a)
        {
            case 1:
                a = Init_BTNode(&T);
                flag++;
                if(a == 1)
                {
                    printf(" success\n");
                }
                else
                {
                    printf(" fail\n");
                }
                break;
            case 2:
                if(flag == 0)
                {
                    printf("  please initialize binary tree fist!\n");
                }
                else
                {
                    Create_BTNode(&T);
                    tag++;
                }
                break;
            case 3:
                if(flag == 0)
                {
                    printf("  please initialize binary tree fist!\n");

                }
                else
                {
                    if(tag == 0)
                    {
                        printf("please build a binary tree first!");
                    }
                    else
                    {
                        int o;
                        printf("1.Previous Order Traverse1\n2.Previous Order Traverse\n3.Infix Order Traverse\n4.Posterior Order Traverse\n");
                        scanf("%d", &o);
                        switch(o)
                        {
                            case 1:
                                PreOrderTraverses1(&T);
                                printf("\n");
                                break;
                            case 2:
                                PreOrderTraverse(&T);
                                printf("\n");
                                break;
                            case 3:
                                InOrderTraverse(&T);
                                printf("\n");
                                break;
                            case 4:
                                PosOrderTraverse(&T);
                                printf("\n");
                                break;
                            default :
                                printf("operating code error\n");
                                break;
                        }


                    }
                }
                break;
            case 4:
                if(flag == 0)
                {
                    printf("  please initialize binary tree fist!\n");
                }
                else
                {
                    if(tag == 0)
                    {
                        printf("please build a binary tree first!");
                    }
                    else
                    {
                        printf("the number of child is : %d\n",child(&T));
                    }
                }
                break;
            case 5:
                if(flag == 0)
                {
                    printf("  please initialize binary tree fist!\n");
                }
                else
                {
                    if(tag == 0)
                    {
                        printf("please build a binary tree first!");
                    }
                    else
                    {
                        printf("the depth is : %d\n", depth(&T));
                    }
                }
                break;
            case 6:
                if(flag == 0)
                {
                    printf("  please initialize binary tree fist!\n");
                }
                else
                {
                    if(tag == 0)
                    {
                        printf("please build a binary tree first!");
                    }
                    else
                    {
                        printf("the leaves child is : %d\n", leafchild(&T));
                    }
                }
                break;
            default:
                printf("  operating code error.\n  please enter again.\n");
        }


    }

    return 0;
}
二叉树是一种非常重要的数据结构,它的基本操作包括创建、销毁、遍历、查找等。下面是二叉树基本操作的实现方法: 1. 创建二叉树:通过前序遍历的数组构建二叉树,其中 '#' 表示空节点。具体实现方法可以参考引用中的 BinaryTreeCreate 函数。 2. 销毁二叉树遍历二叉树,依次释放每个节点的内存空间。具体实现方法可以参考引用中的 BinaryTreeDestory 函数。 3. 遍历二叉树二叉树遍历包括前序遍历、中序遍历、后序遍历和层序遍历。具体实现方法可以参考引用中的 BinaryTreePrevOrder、BinaryTreeInOrder、BinaryTreePostOrder 和 BinaryTreeLevelOrder 函数。 4. 查找二叉树节点:在二叉树中查找值为 x 的节点,具体实现方法可以参考引用中的 BinaryTreeFind 函数。 5. 计算二叉树节点个数:计算二叉树中节点的个数,具体实现方法可以参考引用[2]中的 BinaryTreeSize 函数。 6. 计算二叉树叶子节点个数:计算二叉树中叶子节点的个数,具体实现方法可以参考引用中的 BinaryTreeLeafSize 函数。 7. 计算二叉树第 k 层节点个数:计算二叉树中第 k 层节点的个数,具体实现方法可以参考引用中的 BinaryTreeLevelKSize 函数。 8. 判断二叉树是否是完全二叉树:判断二叉树是否是完全二叉树,具体实现方法可以参考引用中的 BinaryTreeComplete 函数。 9. 计算二叉树的深度:计算二叉树的深度,具体实现方法可以参考引用中的 BinaryTreeDeep 函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值