数据结构_二叉树的基本操作

二叉树的定义

typedef int BTDataType;
typedef struct BTNode
{
    struct BTNode* _left;
    struct BTNode* _right;
    BTDataType _data;
}BTNode;

二叉树的接口实现

BTNode* BuyBTNode(BTDataType x)   //树的节点
{
    BTNode * cur = (BTNode*)malloc(sizeof(BTNode));
    assert(cur);
    cur->_data = x;
    cur->_left = NULL;
    cur->_right = NULL;

    return cur;
}

// 创建二叉树 
BTNode* CreateBTree(BTDataType* a, size_t* pIndex, BTDataType invalid)   //a是数组,invalid是空的符号,pIndex是计数器,记录取数据的下标
{
    assert(a);

    BTNode* tree = NULL;
    if (a[*pIndex] == invalid)
    {
        tree = NULL;
    }
    else
    {
        tree = BuyBTNode(a[*pIndex]);

        (*pIndex)++;
        tree->_left = CreateBTree(a, pIndex, invalid);   //左子树

        (*pIndex)++;
        tree->_right = CreateBTree(a, pIndex, invalid);   //右子树
    }
    return tree;
}

void BTreePrevOrder(BTNode* root)  //前序遍历
{
    if (root == NULL)
    {
        return;
    }
    printf("%d ", root->_data);

    BTreePrevOrder(root->_left);
    BTreePrevOrder(root->_right);
}

void BTreeInOrder(BTNode* root)    //中序遍历
{
    if (root == NULL)
    {
        return;
    }

    BTreeInOrder(root->_left);
    printf("%d ", root->_data);
    BTreeInOrder(root->_right);

}
void BTreePostOrder(BTNode* root)   //后序遍历
{
    if (root==NULL)
    {
        return;
    }

    BTreePostOrder(root->_left);
    BTreePostOrder(root->_right);
    printf("%d ", root->_data);
}

size_t BTreeSize(BTNode* root)     //树的结点数
{
    if (root == NULL)
        return 0;
    return 1 + BTreeSize(root->_left) + BTreeSize(root->_right);   //自己+左子树节点个数+右子树节点个数
}

size_t BTreeLeafSize(BTNode* root)         //叶子数
{
    if (root == NULL)
    {
        return 0;
    }
    if (root->_left == NULL&&root->_right == NULL)
    {
        return 1;
    }
    return BTreeLeafSize(root->_left) + BTreeLeafSize(root->_right);
}

size_t BTreeKLevelSize(BTNode* root, size_t k)     //第K层结点数
{
    if (root == NULL)
    {
        return 0;
    }
    else if (k == 0)
    {
        return 1;
    }
    else
        return BTreeKLevelSize(root->_left, k - 1) + BTreeKLevelSize(root->_right, k - 1);
}

size_t BTreeDepth(BTNode* root)     //数的深度
{
    size_t ldepth;
    size_t rdepth;
    if (root == NULL)
        return 0;
    ldepth = BTreeDepth(root->_left);
    rdepth = BTreeDepth(root->_right);
    return  ldepth > rdepth ? (ldepth + 1) : (rdepth + 1);
}

BTNode* BTreeFind(BTNode* root, BTDataType x)    //查找
{
    BTNode* lnode = NULL, *rnode = NULL;
    if (root == NULL)
        return NULL;
    if (root->_data == x)
        return root;

    lnode = BTreeFind(root->_left, x);
    if (lnode != NULL)
        return lnode;

    rnode = BTreeFind(root->_right, x);
    if (rnode != NULL)
        return rnode;

    return NULL;
}

void BTreeLevelOrder(BTNode* root)    //层序遍历 
{
    Queue queue;
    QueueInit(&queue);
    BTNode* cur = root;

    if (cur != NULL)
    {
        QueuePush(&queue,cur);
    }
    while (QueueEmpty(&queue))
    {
        cur = QueueFront(&queue);
        printf("%d ", cur->_data);
        QueuePop(&queue);

        if (cur->_left != NULL)
        {
            QueuePush(&queue, cur->_left);
        }
        if (cur->_right != NULL)
        {
            QueuePush(&queue, cur->_right);
        }
    }
    printf("\n");
}

int IsCompleteBTree(BTNode* root)  // 判断完全二叉树  层序遍历
{
    Queue q;
    QueueInit(&q);
    if (root != NULL)
        QueuePush(&q, root);

    while (QueueEmpty(&q) != 0)
    {
        BTNode* front = QueueFront(&q);
        QueuePop(&q);

        if (front == NULL)
        {
            break;
        }
        else
        {
            QueuePush(&q, front->_left);
            QueuePush(&q, front->_right);
        }
    }

    while (QueueEmpty(&q) != 0)
    {
        BTNode* front = QueueFront(&q);
        if (front != NULL)
        {
            return 0;
        }
        QueuePop(&q);
    }

    return 1;

}
int IsCompleteBTree1(BTNode* root)    // flag的方式判断 
{
    int flag = 1;
    Queue q;
    QueueInit(&q);

    if (root != NULL)
    {
        QueuePush(&q, root);
    }
    while (QueueEmpty(&q) != 0)
    {
        BTNode* cur = QueueFront(&q);
        QueuePop(&q);
        if (cur == NULL)
        {
            break;
        }
        else
        {
            if (cur->_left == NULL)
            {
                flag = 0;
            }
            else
            {
                QueuePush(&q, cur->_left);
            }
            if (cur->_right == NULL)
            {
                flag = 0;
            }
            else
            {
                if (flag == 0)
                    return 0;

                QueuePush(&q, cur->_right);
            }
        }
    }
    return 1;
}

// 非递归遍历 
void BTreePrevOrderNonR(BTNode* root)
{
    BTNode* cur = root;
    Stack stack;
    StackInit(&stack);

    while (cur != NULL || StackEmpty(&stack) != 0)
    {
        while (cur != NULL)
        {
            printf("%d ", cur->_data);
            StackPush(&stack, cur);
            cur = cur->_left;
        }

        BTNode* top = StackTop(&stack);
        StackPop(&stack);
        cur = top->_right;
    }
    printf("\n");
}

void BTreeInOrderNonR(BTNode* root)
{
    BTNode* cur = root;
    Stack stack;
    StackInit(&stack);

    while (cur != NULL || StackEmpty(&stack) != 0)
    {
        while (cur != NULL)
        {
            StackPush(&stack, cur);
            cur = cur->_left;
        }

        BTNode* top = StackTop(&stack);
        StackPop(&stack);
        printf("%d ", top->_data);
        cur = top->_right;
    }
    printf("\n");
}

void BTreePostOrderNonR(BTNode* root)
{
    BTNode* cur = root;
    BTNode* prev = NULL;
    Stack stack;
    StackInit(&stack);

    while (cur != NULL || StackEmpty(&stack) != 0)
    {
        while (cur != NULL)
        {
            StackPush(&stack, cur);
            cur = cur->_left;
        }

        BTNode* top = StackTop(&stack);

        if (top->_right == NULL || top->_right == prev)
        {
            printf("%d ", top->_data);
            StackPop(&stack);
            prev = top;
        }
        else
        {
            cur = top->_right;
        }

    }
    printf("\n");
}

void DestoryBTree(BTNode** pTree)   //删除
{
    assert(pTree);

    if (*pTree == NULL)
        return;
    DestoryBTree(&(*pTree)->_left);
    DestoryBTree(&(*pTree)->_right);

    free(*pTree);
    *pTree = NULL;
    return;
}

BTNode* BTreeMirror(BTNode* root)   //反转
{
    BTNode* tmp = root->_left;
    if (root == NULL)
        return NULL;
    root->_left = root->_right;
    root->_right = tmp;
    BTreeMirror(root->_left);
    BTreeMirror(root->_right);
    return root;
}

BTNode* BTMirrorNonR(BTNode* root)   //非递归
{
    Queue q;
    QueueInit(&q);
    if (root == NULL)
        return NULL;

    QueuePush(&q, root);
    while (QueueEmpty(&q) != 0)
    {
        BTNode* front = QueueFront(&q);
        QueuePop(&q);
        if (front != NULL)
        {
            BTNode* cur = front->_left;
            front->_left = front->_right;
            front->_right = cur;
            QueuePush(&q, front->_left);
            QueuePush(&q, front->_right);
        }
    }
    return root;    
}

测试用例

#include "BTree.h"

void TestBinaryTree()
{
    int a[] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6, '#', '#', '#' };
//  int a[] = { 1, 2, 3, 4, '#', '#', 5, '#', '#',  '#', '#', 6, '#',9, '#' ,'#'};
    size_t index = 0;
    BTNode* tree = CreateBTree(a, &index, '#');
    BTreePrevOrder(tree);
    printf("\n");
    BTreePrevOrderNonR(tree);
    BTreeInOrder(tree);
    printf("\n");
    BTreePostOrder(tree);
    printf("\n");
    BTreeLevelOrder(tree);
    printf("\n");

    printf("BTreeSize?%d\n", BTreeSize(tree));
    printf("BTreeLeafSize?%d\n", BTreeLeafSize(tree));
    printf("BTreeKLevelSize?%d\n", BTreeKLevelSize(tree, 2));
    printf("BTreeDepth?%d\n", BTreeDepth(tree));
    printf("IsCompleteBTree?%d\n", IsCompleteBTree(tree));
    printf("IsCompleteBTree?%d\n", IsCompleteBTree1(tree));

}

int main()
{
    TestBinaryTree();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值