二叉树基本操作(下)

二叉树基本操作

 1. 求二叉树的高度
 2. 求二叉树叶子结点的个数
 3. 求二叉树结点的个数
 4. 求二叉树第K层结点的个数
 5. 判断一个节点是否在一棵二叉树中
 6. 获取一个节点的双亲结点
 7. 获取一个节点的左孩子结点
 8. 求二叉树的镜像(递归&非递归)
 9.判断一棵二叉树是否为完全二叉树(层序遍历变形)
 完整源代码
 1、BinaryTree.h
 

#ifndef __TREE_H__
#define __TREE_H__

#include<stdio.h>
#include <stdlib.h>
#include<string.h>
#include<assert.h>

typedef int BTDataType;

typedef struct BTNode //树结构
{
    BTDataType data;
    struct BTNode *left;
    struct BTNode *right;
}BTNode;

BTNode* CreateBTree(BTDataType *a,size_t *index,BTDataType invalid);  //创建一棵二叉树

size_t BTreeLenth(BTNode* root); // 求二叉树的高度
size_t BTreeLeafNumber(BTNode* root); //求二叉树叶子结点的个数
size_t BTreeNodeNumber(BTNode *root);// 求二叉树结点的个数
size_t BTreeKLevelNodeNumber(BTNode* root, size_t k); //求二叉树第K层结点的个数
BTNode* BTreeNodeFind(BTNode* root, BTDataType x) ; //判断一个节点是否在一棵二叉树中
BTNode* GetBTreeParents(BTNode *root,BTNode *node); //获取一个节点的双亲结点
BTNode* GetNodeLeftChild(BTNode *root,BTNode *node);//获取一个节点的左孩子结点
BTNode* BTreeMirrorR(BTNode *root);// 求二叉树的镜像(递归&非递归)
BTNode* BTreeMirror(BTNode *root);// 求二叉树的镜像(非递归)
size_t CheckBTree(BTNode *root);// 判断一棵二叉树是否为完全二叉树(层序遍历变形)
size_t CheckBTreeF(BTNode* root) ;// flag的方式判断 

#endif //__TREE_H__

2、BinaryTree.c

size_t BTreeLenth(BTNode* root) // 求二叉树的高度
{
    if (root==NULL)
    {
        return 0;
    }

    if (BTreeLenth(root->left)>=BTreeLenth(root->right))  //返回左右高度中高的一个再加一
        return BTreeLenth(root->left)+1;
    else
        return BTreeLenth(root->right)+1;

}

size_t BTreeLeafNumber(BTNode* root) //求二叉树叶子结点的个数
{
    if (root == NULL)  //递归结束条件
    {
        return 0;
    }

    if (NULL == root->right)   //当左边为NULL时,如果右边也为NULL,则为叶子节点
        return 1;

    return BTreeLeafNumber(root->left)+BTreeLeafNumber(root->right);  //左子树叶子+右子树叶子
}

size_t BTreeNodeNumber(BTNode *root)// 求二叉树结点的个数
{
    if (NULL == root)  //递归结束条件
    {
        return 0;
    }

    return BTreeNodeNumber(root->left) + BTreeNodeNumber(root->right)+1; //左子树节点数 + 右子树节点 + 1
}

size_t BTreeKLevelNodeNumber(BTNode* root, size_t k) //求二叉树第K层结点的个数
{
    if (root == NULL || k<1)
    {
        return 0;
    }

    if (k==1)
    {
        return 1;
    }
    //二叉树不为空,且左右子树不同时为空,返回左子树中叶子节点个数加上右子树中叶子节点个数   
    return BTreeKLevelNodeNumber(root->left,k-1) + BTreeKLevelNodeNumber(root->right,k-1);
}

BTNode* BTreeNodeFind(BTNode* root, BTDataType x) //判断一个节点是否在一棵二叉树中(层序遍历比较)
{
    Queue q;
    BTNode *tmp = root;
    QueueInit(&q);
    QueuePush(&q,tmp);
    while (QueueEmpty(&q)) //取队头元素访问,并同时入队该元素的左右非空子树节点
    {
        BTNode *front = QueueFront(&q);
        QueuePop(&q);
        if (front->data == x) //找到该元素则返回该元素地址
        {
            return front;
        }
        if (front->left)
        {
            QueuePush(&q,front->left);
        }
        if (front->right)
        {
            QueuePush(&q,front->right);
        }
    }
    return NULL; //没找到
}

BTNode* GetBTreeParents(BTNode *root,BTNode *node) //获取一个节点的双亲结点(层序遍历)
{
    Queue q;
    BTNode *tmp = root;
    if (root == node)  //该节点为根节点
    {
        return NULL;
    }
    QueueInit(&q);
    QueuePush(&q,tmp);
    while (QueueEmpty(&q)) //取队头元素访问,并同时入队该元素的左右非空子树节点
    {
        BTNode *front = QueueFront(&q);
        QueuePop(&q);

        if (front->left == node)
            return front;
        else
            QueuePush(&q,front->left);
        if (front->right == node)
            return front;
        else
            QueuePush(&q,front->right);
    }
    return NULL; //没有该节点
}

BTNode* GetNodeLeftChild(BTNode *root,BTNode *node)//获取一个节点的左孩子结点(层序遍历)
{
    Queue q;
    BTNode *tmp = root;
    QueueInit(&q);
    QueuePush(&q,tmp);
    while (QueueEmpty(&q)) //取队头元素访问,并同时入队该元素的左右非空子树节点
    {
        BTNode *front = QueueFront(&q);
        QueuePop(&q);

        if (front== node)
            return front->left;
        else
        {
            QueuePush(&q,front->left);
            QueuePush(&q,front->right);
        }
    }
    return NULL; //没有该节点
}

static void Swap(BTNode **left,BTNode **right)  //交换
{
    BTNode *tmp;
    tmp = *left;
    *left = *right;
    *right = tmp;
}

BTNode* BTreeMirrorR(BTNode *root)// 求二叉树的镜像(递归)
{
    if (root == NULL)
    {
        return NULL;
    }
    BTreeMirrorR(root->left);
    BTreeMirrorR(root->right);
    Swap(&root->left,&root->right);  //左右交换

    return root;
}

BTNode* BTreeMirror(BTNode *root)// 求二叉树的镜像(非递归)
{
    Stack s;
    BTNode *top = NULL;
    BTNode *tmp = root;
    StackInit(&s);
    while (StackEmpty(&s) != 0 || NULL != tmp) 
    {
        while (tmp) //遍历左子树
        {
            StackPush(&s,tmp); //左子树不为空则入栈
            tmp = tmp->left;
        }

        top = StackTop(&s); //左子树为空,取栈顶
        Swap(&top->left,&top->right);
        StackPop(&s);

        tmp = top->right; //右子树
    }
    return root;
}

size_t CheckBTree(BTNode *root)// 判断一棵二叉树是否为完全二叉树(层序遍历变形)
{
    Queue q;
    BTNode *tmp = root;
    QueueInit(&q);
    QueuePush(&q,tmp);
    while (QueueEmpty(&q)) //取队头元素访问,并同时入队该元素的左右非空子树节点
    {
        BTNode *front = QueueFront(&q);
        if (front)
            QueuePop(&q);
        else
            break;
        QueuePush(&q,front->left);
        QueuePush(&q,front->right);
    }
    while (QueueEmpty(&q)) //如果从第一个空元素后面没有非空元素,则是完全二叉树,否则,不是。
    {
        BTNode *front = QueueFront(&q);
        if (front)
        {
            return 0;
        }
        QueuePop(&q);
    }
    return 1;
}

size_t CheckBTreeF(BTNode *root)  // flag的方式判断 
{
    Stack s;
    size_t flag = 1;
    BTNode *top = NULL;
    BTNode *tmp = root;
    StackInit(&s);
    while (StackEmpty(&s) || tmp ) 
    {
        while (tmp) //遍历左子树
        {
            StackPush(&s,tmp); //左子树不为空则入栈
            tmp = tmp->left;
            flag = 0;
        }

        top = StackTop(&s); //左子树为空,取栈顶
        StackPop(&s);
        if (!top->left && top->right) //左子树 = NULL,右子树 != NULL.
        {
            flag = 1;
            break;
        }
        tmp = top->right; //访问右子树

    }
    if (flag == 0)
        return 1;
    else
        return 0;
}

3、Test.c

void Test2()
{
    BTDataType a[] = {1,2,3,'#','#',4,5,'#','#',6,'#','#',7,8,'#',9,'#','#','#'};
    BTDataType index = 0;
    BTNode *tree = CreateBTree(a,&index,'#');
    BTreePrevOrderR(tree); //前序遍历

    printf("%d \n",BTreeLenth(tree));
    printf("%d \n",BTreeLeafNumber(tree));
    printf("%d \n",BTreeNodeNumber(tree));
    printf("%d \n",BTreeKLevelNodeNumber(tree,3));
    printf("%p \n",BTreeNodeFind(tree,2));
    printf("%p \n",GetBTreeParents(tree,BTreeNodeFind(tree,4)));
    printf("%p \n",GetNodeLeftChild(tree,BTreeNodeFind(tree,1)));
    tree = BTreeMirrorR(tree);
    tree = BTreeMirror(tree);
    printf("%d \n",CheckBTree(tree));
    printf("%d \n",CheckBTreeF(tree));
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙跃十二

写的不错,给点鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值