- 作者:邹祁峰
- 邮箱:Qifeng.zou.job@hotmail.com
- 博客:http://blog.csdn.net/qifengzou
- 日期:2013.12.17 11:00
- 转载请注明来自”祁峰“的CSDN博客
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()将会打印出所输入的数字构造的平衡二叉树的结构,如下图所示:
图1 测试结果