算法导论 之 平衡二叉树 - 打印 - 递归[C语言]

1 前言

   在之前的博文《算法导论 之 平衡二叉树 – 插入、查询、销毁》中已经给出了构建平衡二叉树的C语言实现过程,但随着结点的增加和树结构的不断旋转变化,也许插入、查找、删除等操作还存在一定的BUG,经过一段时间后,我很难知道当前平衡二叉树的实际结构,因此,增加打印平衡二叉树当前结构的函数显得十分必要。


2 代码实现

    此段代码中出现的部分结构体、枚举、宏和函数等已在博文《算法导论 之 平衡二叉树 – 插入、查询、销毁》中定义和实现,请结合以上博文一起阅读。

/******************************************************************************
 **函数名称: val_print
 **功    能: 打印平衡二叉树(外部接口)
 **输入参数: 
 **     tree: 平衡二叉树
 **输出参数: NONE
 **返    回: VOID
 **实现描述: 
 **注意事项: 
 **作    者: # Qifeng.zou # 2013.12.17 #
 ******************************************************************************/
int avl_print(const avl_tree_t *tree)
{
    if(NULL == tree->root) {
        return AVL_SUCCESS;
    }
    
    _avl_print(tree->root, 0);         /* 打印结点 */

    return AVL_SUCCESS;
}

代码1 打印AVL(对外接口)

/******************************************************************************
 **函数名称: avl_print_head
 **功    能: 打印结点头(内部接口)
 **输入参数: 
 **     node: 被打印的结点
 **     depth: 结点深度
 **输出参数: NONE
 **返    回: VOID
 **实现描述: 
 **注意事项: 
 **作    者: # Qifeng.zou # 2013.12.17 #
 ******************************************************************************/
void avl_print_head(avl_node_t *node, int depth)
{
    int idx = 0;
    avl_node_t *parent = node->parent;
    
    while(depth > 1) {
        depth--;
        if(1 == depth) {
            fprintf(stderr, "|");
            for(idx=0; idx<8; idx++) {
                if(0 == idx) {
                    if(parent->lchild == node) {
                        fprintf(stderr, "l");
                    }
                    else {
                        fprintf(stderr, "r");
                    }
                }
                else {
                    fprintf(stderr, "-");
                }
            }
        }
        else {
            fprintf(stderr, "|\t");
        }
    }
    
    if((NULL == node->lchild)
        && (NULL == node->rchild)) {
        fprintf(stderr, "<%03d:%d/>\n", node->key, node->bf);
    }
    else {
        fprintf(stderr, "<%03d:%d>\n", node->key, node->bf);
    }
}

代码2  打印节点头

/******************************************************************************
 **函数名称: avl_print_tail
 **功    能: 打印结点尾(内部接口)
 **输入参数: 
 **     node: 被打印的结点
 **     depth: 结点深度
 **输出参数: NONE
 **返    回: VOID
 **实现描述: 
 **注意事项: 
 **作    者: # Qifeng.zou # 2013.12.17 #
 ******************************************************************************/
void avl_print_tail(avl_node_t *node, int depth)
{
    int idx = 0;

    if((NULL == node->lchild)
        && (NULL == node->rchild)) {
        return;
    }

    while(depth > 1) {
        fprintf(stderr, "|\t");
        depth--;
    }

    fprintf(stderr, "\n", node->key);
}

代码3 打印节点尾

/******************************************************************************
 **函数名称: _avl_print
 **功    能: 打印平衡二叉树(内部接口)
 **输入参数: 
 **     node: 被打印的结点
 **     stack: 栈
 **输出参数: NONE
 **返    回: VOID
 **实现描述: 
 **     1. 结点入栈 
 **     2. 打印该结点(头)
 **     3. 打印该结点的右子树
 **     4. 打印该结点的左子树
 **     5. 打印该结点(尾)
 **     6. 结点出栈
 **注意事项: 
 **作    者: # Qifeng.zou # 2013.12.17 #
 ******************************************************************************/
static int _avl_print(const avl_node_t *node, int depth)
{
    /* 1. 打印结点头 */
    avl_print_head(node, depth);

    /* 2. 打印右子树 */
    if(NULL != node->rchild) {
        _avl_print(node->rchild, depth+1);
    }

    /* 3. 打印左子树 */
    if(NULL != node->lchild) {
        _avl_print(node->lchild, depth+1);
    }

    /* 4. 打印结点尾 */
    avl_print_tail(node, depth);    

    return AVL_SUCCESS;
}

代码4 打印结点(内部接口)

3 结果展示

测试主函数如下:

#define INPUT_MAX_LEN  (16)
int main(void)
{
    int ret = 0, key = 0;
    avl_tree_t tree;
    avl_node_t *node = NULL;
    char input[INPUT_MAX_LEN] = {0};

    memset(&tree, 0, sizeof(tree));

    while(1) {
        memset(input, 0, sizeof(input));

        scanf(" %s", input);
        key = atoi(input)%1000;

        if(!strcasecmp(input, "quit")
            || !strcasecmp(input, "exit")
            || !strcasecmp(input, "q")) {
            fprintf(stderr, "Quit!\n");
            break;
        }

        ret = avl_insert(&tree, key);
        if(AVL_FAILED == ret) {
            fprintf(stderr, "Insert failed!\n");
            continue;
        }
        else if(AVL_NODE_EXIST == ret) {
            fprintf(stderr, "Node exist!\n");
            continue;
        }

        avl_print(&tree);
    }

    avl_destory(&tree);
    return 0;
}

代码5 测试程序

绘制平衡二叉树:

    运行代码5中的主程序,随机输入数字,avl_print()将会打印出所输入的数字构造的平衡二叉树的结构,如下图所示:

《算法导论 之 平衡二叉树 - 打印 - 递归[C语言]》

图1 测试结果





    原文作者:平衡二叉树
    原文地址: https://blog.csdn.net/qifengzou/article/details/17372751
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞