算法精解----12、二叉树的实现及应用-表达式处理

本文介绍了二叉树的基本概念,包括平衡二叉树、AVL树及其特性,并详细展示了二叉树的C语言实现代码。同时,文章还探讨了二叉树的四种遍历方法及其实现方式,并通过具体的例子说明了如何利用这些遍历方法处理表达式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、树的平衡:对于指定数量的节点,保证树的高度尽可能短。即节点加入下一层之前必须保证本层节点满。

2、AVL树是平衡二叉搜索树的一种。

3、四种周游算法:先序遍历、中序遍历、后序遍历、层级遍历
这里写图片描述

4、二叉树实现代码
(1)数据结构

#ifndef _BITTREE_H
#define _BITTREE
typedef struct _BiTreeNode{
    void *data;
    struct _BiTreeNode *left;
    struct _BiTreeNode *right;
}BiTreeNode;

typedef struct _BiTree{
    int size;
    BiTreeNode *root;
    int compare (const void *data1, const void *data2);
    void (*destroy)(void *data);
}BiTree;
#define bittree_size(tree)  tree->size      
#define bittree_data(node)  node->data
#define bittree_left(node)  node->left
#define bittree_right(node) node->right
#define bittree_root(node)  node->root
void bittree_init(BiTree *bittree, void (*destroy)(void *data));
void bittree_destroy(BiTree *bittree);
int bittree_ins_left(BiTree *bittree, BiTreeNode *node,const void *data);
int bittree_ins_right(BiTree *bittree, BiTreeNode *node,const void *data);
int bittree_rem_left(BiTree *bittree, BiTreeNode *node);
int bittree_rem_right(BiTree *bittree, BiTreeNode *node);
int bittree_merge(BiTree *merge_tree, BiTree *left_tree, BiTree *right_tree, const void *data)

#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bittree.h"

void bittree_init(BiTree *bittree, void (*destroy)(void *data))
{
    bittree->size = 0;
    bittree->root = NULL;
    bittree->destroy = destroy;
    return;
}

void bittree_destroy(BiTree *bittree)
{
    bittree_rem_left(bittree, NULL);
    memset(bittree, 0, sizeof(BiTree));
    return;
}

//在node左子叶插入节点(左子树) ,如果node=NULL则插入第一个节点(根节点) 
int bittree_ins_left(BiTree *bittree, BiTreeNode *node, const void *data)
{
    BiTreeNode *new_node, **position;//position决定插入节点的位置 

    if(node == NULL)
    {
        if(bittree_size(tree)>0)
            return -1;
        position = &bittree->root;
    } 
    else{
        if(bittree_left(node)!=NULL)
            return -1;
        position = &node->left;
    }

    if((new_node = (BiTreeNode *)malloc(sizeof(BiTreeNode))) == NULL)
        return -1;
    *position = new_node;

    new_node->data = (void *)data;
    new_node->left = NULL;
    new_node->right = NULL;
    bittree->size++;
    return 0;
}
int bittree_ins_right(BiTree *bittree, BiTreeNode *node, void *data)
{
    BiTreeNode *new_node, **position;//position决定插入节点的位置 

    if(node == NULL)
    {
        if(bittree_size(tree)>0)
            return -1;
        position = &bittree->root;
    } 
    else{
        if(bittree_right(node)!=NULL)
            return -1;
        position = &node->right;
    }

    if((new_node = (BiTreeNode *)malloc(sizeof(BiTreeNode))) == NULL)
        return -1;
    *position = new_node;

    new_node->data = (void *)data;
    new_node->left = NULL;
    new_node->right = NULL;
    bittree->size++;
    return 0;
}

//删除node节点的左子树 ,如果 node等于NULL,则从头结点开始删除整个树 
//要删除的节点存在子树,则要递归删除 
void bittree_rem_left(BiTree *bittree, BiTreeNode *node)
{
    BiTreeNode **position;
    if(bittree_size(bittree) == 0)
        return;

    if(node == NULL)
        position = &bittree->root;
    else 
        position = node->left;

    //如果要删除的节点存在子树,则递归删除 
    if(*position != NULL)
    {
        bittree_rem_left(bittree, *position);
        bittree_rem_right(bittree, *position);  

        bittree->destroy(position->data);
        free(position);
        *position=NULL; 
        bittree->size--;
    }
    return 0;
}

int bittree_rem_right(BiTree *bittree, BiTreeNode *node)
{
    BiTreeNode **position;
    if(bittree_size(bittree) == 0)
        return;

    if(node == NULL)
        position = &bittree->root;
    else 
        position = node->right;

    //如果要删除的节点存在子树,则递归删除 
    if(*position != NULL)
    {
        bittree_rem_left(bittree, *position);
        bittree_rem_right(bittree, *position);  

        bittree->destroy(position->data);
        free(position);
        *position=NULL; 
        bittree->size--;
    }
    return 0;
}

//合并两颗树 ,创建一个头结点,数据为data,合并的两棵树分别为左右子树 
int bittree_merge(BiTree *merge_tree, BiTree *left_tree, BiTree *right_tree, const void *data)
{
    bittree_init(merge_tree, left_tree->destroy);

    //先插入头部父节点 
    bittree_ins_left(merge_tree, NULL,data); 
    bittree_root(merge_tree)->left =  bittree_root(left_tree);
    bittree_root(merge_tree)->right =  bittree_root(right_tree);
    merge_tree->size = left_tree->size + right_tree->size;

    //关闭左右子树的属性
    left_tree->size = 0;
    left_tree->root = NULL;
    right_tree->size = 0;
    right_tree->root = NULL;
    return 0;
}

5、遍历二叉树应用-表达式处理代码
遍历的目的是把二叉树中元素提取出来以链表的新式组织起来

表达式存储在二叉树中,操作符存储在父节点,其操作数由其子节点延伸出来的子树组成。后缀表达式(后续遍历)最适合计算机处理。只有最底层的叶为数字。
这里写图片描述
如图表达式为:(3+(2*3) ) - (6 /3 )

(1)前缀表达式: (- (+ 3(* 2 3)) (/ 6 3))

//链表插入顺序:父节点数据,左子树得出的数据,右子树得出的数据
int preorder(const BiTreeNode *node, List *list)
{
    if(!bitree_is_eob(node))
    {
        if(list_ins_next(list, list_tail(list), bitree_data(node)) != 0)
            return -1;
        if(!bitree_is_eob(bitree_left(node)))
            if(preorder(bitree_left(node), list) != 0);
                return -1;
        if(!bitree_is_eob(bitree_right(node)))
            if(preorder(bitree_right(node), list) != 0);
                return -1;
    } 
    return 0;
}

(2)中缀表达式: (3 + (2*3)) - (6 /3)

//链表插入顺序:左子树得出的数据,父节点数据,右子树得出的数据
//子树递归得到子叶的值
int inorder(const BiTreeNode *node, List *list)
{
    if(!bitree_is_eob(node))
    {
        if(!bitree_is_eob(bitree_left(node)))
            if(inorder(bitree_left(node), list) != 0);
                return -1;

        if(list_ins_next(list, list_tail(list), bitree_data(node)) != 0)
            return -1;

        if(!bitree_is_eob(bitree_right(node)))
            if(inorder(bitree_right(node), list) != 0);
                return -1;
    } 
    return 0;
}

(3)后缀表达式:((3 (2 3 *) +) (6 3 /) - )

//链表插入顺序:左子树得出的数据,右子树得出的数据,父节点数据
int postorder(const BiTreeNode *node, List *list)
{
    if(!bitree_is_eob(node))
    {
        if(!bitree_is_eob(bitree_left(node)))
            if(inorder(bitree_left(node), list) != 0);
                return -1;

        if(!bitree_is_eob(bitree_right(node)))
            if(postorder(bitree_right(node), list) != 0);
                return -1;

        if(list_ins_next(list, list_tail(list), bitree_data(node)) != 0)
            return -1;
    } 
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值