在之前的博文《算法导论 之 平衡二叉树 - 插入、查询、销毁》中已经给出了构建平衡二叉树的C语言实现过程,但随着结点的增加和树结构的不断旋转变化,也许插入、查找、删除等操作还存在一定的BUG,经过一段时间后,我很难知道当前平衡二叉树的实际结构,因此,增加打印平衡二叉树当前结构的函数显得十分必要。
此段代码中出现的部分结构体、枚举、宏和函数等已在博文《算法导论 之 平衡二叉树 - 插入、查询、销毁》中定义和实现,请结合以上博文一起阅读。
/****************************************************************************** **函数名称: 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; }
/****************************************************************************** **函数名称: 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); } }
/****************************************************************************** **函数名称: 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); }
/****************************************************************************** **函数名称: _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; }
测试主函数如下:
#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中的主程序,随机输入数字,avl_print()将会打印出所输入的数字构造的平衡二叉树的结构,如下图所示:
图1 测试结果