(1)bistree.h
/*****************************************************************************
* *
* ------------------------------- bistree.h ------------------------------ *
* *
*****************************************************************************/
#ifndef BISTREE_H
#define BISTREE_H
#include "bitree.h"
/*****************************************************************************
* *
* Define balance factors for AVL trees. *
* *
*****************************************************************************/
#define AVL_LFT_HEAVY 1
#define AVL_BALANCED 0
#define AVL_RGT_HEAVY -1
/*****************************************************************************
* *
* Define a structure for nodes in AVL trees. *
* *
*****************************************************************************/
typedef struct AvlNode_ {
void *data; // 结点数据
int hidden; // 这里的删除仅仅是将该结点隐藏
int factor; // 平衡因子
} AvlNode;
/*****************************************************************************
* *
* Implement binary search trees as binary trees. *
* *
*****************************************************************************/
typedef BiTree BisTree;
/*****************************************************************************
* *
* --------------------------- Public Interface --------------------------- *
* *
*****************************************************************************/
void bistree_init(BisTree *tree, int (*compare)(const void *key1, const void
*key2), void (*destroy)(void *data));
void bistree_destroy(BisTree *tree);
int bistree_insert(BisTree *tree, const void *data);
int bistree_remove(BisTree *tree, const void *data);
int bistree_lookup(BisTree *tree, void **data);
#define bistree_size(tree) ((tree)->size)
#endif
(2)bistree.c
/*****************************************************************************
* *
* ------------------------------- bistree.c ------------------------------ *
* *
*****************************************************************************/
#include <stdlib.h>
#include <string.h>
#include "bistree.h"
static void destroy_right(BisTree *tree, BiTreeNode *node);
/*****************************************************************************
* *
* ------------------------------ rotate_left ----------------------------- *
* *
*****************************************************************************/
static void rotate_left(BiTreeNode **node) {
// node 表示最近的不平衡祖先结点,平衡因子绝对值为2
// 注意双指针的使用,确保修改值的正确性
BiTreeNode *left, // left = node->left
*grandchild; // grandchild = left->child,child->{left,right}
left = bitree_left(*node);
if (((AvlNode *)bitree_data(left))->factor == AVL_LFT_HEAVY) { // LL
// 原始二叉树中的数据 void *data,现在变为AvlNode *data
/**************************************************************************
* *
* Perform an LL rotation. *
* *
**************************************************************************/
// left pointer of A to the right child of left
bitree_left(*node) = bitree_right(left);
// right pointer of left to A
bitree_right(left) = *node;
// 调节平衡因子
((AvlNode *)bitree_data(*node))->factor = AVL_BALANCED;
((AvlNode *)bitree_data(left))->factor = AVL_BALANCED;
// pointer referencing A to lef
*node = left; // 修改的是原地址中的数据
}
else { // LR
/**************************************************************************
* *
* Perform an LR rotation. *
* *
**************************************************************************/
// grandchild be the right child of left
grandchild = bitree_right(left);
// right child of left to the left child of grandchild
bitree_right(left) = bitree_left(grandchild);
// left child of grandchild to left
bitree_left(grandchild) = left;
// left child of A to the right child of grandchild
bitree_left(*node) = bitree_right(grandchild);
// right child of grandchild to A
bitree_right(grandchild) = *node;
// 根据grandchild的平衡因子分情况调整各结点的平衡因子
switch (((AvlNode *)bitree_data(grandchild))->factor) {
case AVL_LFT_HEAVY: // 1
((AvlNode *)bitree_data(*node))->factor = AVL_RGT_HEAVY; // -1
((AvlNode *)bitree_data(left))->factor = AVL_BALANCED; // 0
break;
case AVL_BALANCED: // 0
((AvlNode *)bitree_data(*node))->factor = AVL_BALANCED; // 0
((AvlNode *)bitree_data(left))->factor = AVL_BALANCED; // 0
break;
case AVL_RGT_HEAVY: // -1
((AvlNode *)bitree_data(*node))->factor = AVL_BALANCED; // 0
((AvlNode *)bitree_data(left))->factor = AVL_LFT_HEAVY; // 1
break;
}
((AvlNode *)bitree_data(grandchild))->factor = AVL_BALANCED; // 0
// pointer referencing A to grandchild
*node = grandchild;
}
return;
}
/*****************************************************************************
* *
* ----------------------------- rotate_right ----------------------------- *
* *
*****************************************************************************/
static void rotate_right(BiTreeNode **node) {
// node 表示最近的不平衡祖先结点,平衡因子绝对值为2
// 注意双指针的使用,确保修改值的正确性
BiTreeNode *right, // right = node->right
*grandchild; // grandchild = right->child,child->{left,right}
right = bitree_right(*node);
if (((AvlNode *)bitree_data(right))->factor == AVL_RGT_HEAVY) { // RR
// 原始二叉树中的数据 void *data,现在变为AvlNode *data
/**************************************************************************
* *
* Perform an RR rotation. *
* *
**************************************************************************/
// right pointer of A to the left child of right
bitree_right(*node) = bitree_left(right);
// left pointer of right to A
bitree_left(right) = *node;
// 调节平衡因子
((AvlNode *)bitree_data(*node))->factor = AVL_BALANCED; // 0
((AvlNode *)bitree_data(right))->factor = AVL_BALANCED; // 0
// pointer referencing A to right
*node = right;
}
else { // RL
/**************************************************************************
* *
* Perform an RL rotation. *
* *
**************************************************************************/
// grandchild be the left child of right
grandchild = bitree_left(right);
// left child of right to the right child of grandchild
bitree_left(right) = bitree_right(grandchild);
// right child of grandchild to right
bitree_right(grandchild) = right;
// right child of A to the left child of grandchild
bitree_right(*node) = bitree_left(grandchild);
// left child of grandchild to A
bitree_left(grandchild) = *node;
// 根据grandchild的平衡因子分情况调整各结点的平衡因子
switch (((AvlNode *)bitree_data(grandchild))->factor) {
case AVL_LFT_HEAVY: // 1
((AvlNode *)bitree_data(*node))->factor = AVL_BALANCED; // 0
((AvlNode *)bitree_data(right))->factor = AVL_RGT_HEAVY; // -1
break;
case AVL_BALANCED: // 0
((AvlNode *)bitree_data(*node))->factor = AVL_BALANCED; // 0
((AvlNode *)bitree_data(right))->factor = AVL_BALANCED; // 0
break;
case AVL_RGT_HEAVY: // -1
((AvlNode *)bitree_data(*node))->factor = AVL_LFT_HEAVY; // 1
((AvlNode *)bitree_data(right))->factor = AVL_BALANCED; // 0
break;
}
((AvlNode *)bitree_data(grandchild))->factor = AVL_BALANCED; // 0
// pointer referencing A to grandchild
*node = grandchild;
}
return;
}
/*****************************************************************************
* *
* ----------------------------- destroy_left ----------------------------- *
* *
*****************************************************************************/
static void destroy_left(BisTree *tree, BiTreeNode *node) {
BiTreeNode **position; // 指针的地址,方便后续的释放操作
/*****************************************************************************
* *
* Do not allow destruction of an empty tree. *
* *
*****************************************************************************/
if (bitree_size(tree) == 0) // 空树无需摧毁
return;
/*****************************************************************************
* *
* Determine where to destroy nodes. *
* *
*****************************************************************************/
if (node == NULL)
position = &tree->root; // 删除根结点
else
position = &node->left; // 左子树的根结点
/*****************************************************************************
* *
* Destroy the nodes. *
* *
*****************************************************************************/
if (*position != NULL) { // 递归删除
destroy_left(tree, *position);
destroy_right(tree, *position);
if (tree->destroy != NULL) {
/***********************************************************************
* *
* Call a user-defined function to free dynamically allocated data. *
* *
***********************************************************************/
tree->destroy(((AvlNode *)(*position)->data)->data); // 释放分配的数据 data
}
/**************************************************************************
* *
* Free the AVL data in the node, then free the node itself. *
* *
**************************************************************************/
free((*position)->data); // 释放分配的结构体 AvlNode
free(*position); // 释放分配的结点 BiTreeNode
*position = NULL; // 指针指向NULL
/**************************************************************************
* *
* Adjust the size of the tree to account for the destroyed node. *
* *
**************************************************************************/
tree->size--; // 结点数量减一
}
return;
}
/*****************************************************************************
* *
* ----------------------------- destroy_right ---------------------------- *
* *
*****************************************************************************/
static void destroy_right(BisTree *tree, BiTreeNode *node) {
BiTreeNode **position; // 指针的地址,方便后续的释放操作
/*****************************************************************************
* *
* Do not allow destruction of an empty tree. *
* *
*****************************************************************************/
if (bitree_size(tree) == 0) // 空树无需摧毁
return;
/*****************************************************************************
* *
* Determine where to destroy nodes. *
* *
*****************************************************************************/
if (node == NULL)
position = &tree->root; // 删除根结点
else
position = &node->right; // 右子树的根结点
/*****************************************************************************
* *
* Destroy the nodes. *
* *
*****************************************************************************/
if (*position != NULL) { // 递归删除
destroy_left(tree, *position);
destroy_right(tree, *position);
if (tree->destroy != NULL) {
/***********************************************************************
* *
* Call a user-defined function to free dynamically allocated data. *
* *
***********************************************************************/
tree->destroy(((AvlNode *)(*position)->data)->data); // 释放分配的数据 data
}
/**************************************************************************
* *
* Free the AVL data in the node, then free the node itself. *
* *
**************************************************************************/
free((*position)->data); // 释放分配的结构体 AvlNode
free(*position); // 释放分配的结点 BiTreeNode
*position = NULL; // 指针指向NULL
/**************************************************************************
* *
* Adjust the size of the tree to account for the destroyed node. *
* *
**************************************************************************/
tree->size--; // 结点数量减一
}
return;
}
/*****************************************************************************
* *
* -------------------------------- insert -------------------------------- *
* *
*****************************************************************************/
static int insert(BisTree *tree, BiTreeNode **node, const void *data, int
*balanced) {
// node 表示从哪个结点开始比较,寻找插入的位置
AvlNode *avl_data; // 为新数据分配内存,指向该地址
int cmpval, // 比较方向,向左还是向右判断
retval; // 判断插入数据是否成功
/*****************************************************************************
* *
* Insert the data into the tree. *
* *
*****************************************************************************/
if (bitree_is_eob(*node)) { // 树为空
/**************************************************************************
* *
* Handle insertion into an empty tree. *
* *
**************************************************************************/
if ((avl_data = (AvlNode *)malloc(sizeof(AvlNode))) == NULL) // 分配内存失败
return -1;
avl_data->factor = AVL_BALANCED; // 默认平衡因子为0
avl_data->hidden = 0; // 显示,不隐藏
avl_data->data = (void *)data; // 赋值
return bitree_ins_left(tree, *node, avl_data); // 直接插入
}
else {
/**************************************************************************
* *
* Handle insertion into a tree that is not empty. *
* *
**************************************************************************/
// 与当前值比较大小
cmpval = tree->compare(data, ((AvlNode *)bitree_data(*node))->data);
if (cmpval < 0) { // 在左子树中比较
/***********************************************************************
* *
* Move to the left. *
* *
***********************************************************************/
if (bitree_is_eob(bitree_left(*node))) { // 左孩子为空,插入
if ((avl_data = (AvlNode *)malloc(sizeof(AvlNode))) == NULL) // 分配数据
return -1;
avl_data->factor = AVL_BALANCED; // 默认平衡因子为0
avl_data->hidden = 0; // 显示,不隐藏
avl_data->data = (void *)data; // 赋值
if (bitree_ins_left(tree, *node, avl_data) != 0) // 插入
return -1;
*balanced = 0;
}
else { // 左孩子不为空,递归判断
if ((retval = insert(tree, &bitree_left(*node), data, balanced))
!= 0) { // 插入失败,返回
return retval; // -1
}
}
/***********************************************************************
* *
* Ensure that the tree remains balanced. *
* *
***********************************************************************/
if (!(*balanced)) { // 不平衡,插入的位置是叶子节点的孩子时,可能不平衡
switch (((AvlNode *)bitree_data(*node))->factor) {
case AVL_LFT_HEAVY: // 这种情况不可能出现在递归的末尾,即插入的结点的父节点身上
// 当从最后一层递归返回时,判断最近的平衡因子可能为+-2的结点
rotate_left(node);
*balanced = 1; // 整体为平衡
break;
case AVL_BALANCED: // 0
// 右孩子为空,左孩子不为空
((AvlNode *)bitree_data(*node))->factor = AVL_LFT_HEAVY; // 1,有可能改变原始树的平衡性
break;
case AVL_RGT_HEAVY: // -1
// 左右平衡
((AvlNode *)bitree_data(*node))->factor = AVL_BALANCED; // 0
*balanced = 1; // 并没有改变原始树的平衡性
}
}
} /* if (cmpval < 0) */
else if (cmpval > 0) { // 在右子树中查找
/***********************************************************************
* *
* Move to the right. *
* *
***********************************************************************/
if (bitree_is_eob(bitree_right(*node))) { // 右孩子为空,插入
if ((avl_data = (AvlNode *)malloc(sizeof(AvlNode))) == NULL) // 分配数据
return -1;
avl_data->factor = AVL_BALANCED; // 默认平衡因子为0
avl_data->hidden = 0; // 显示,不隐藏
avl_data->data = (void *)data; // 赋值
if (bitree_ins_right(tree, *node, avl_data) != 0) // 插入
return -1;
*balanced = 0; // 可能不平衡,进入判断阶段
}
else { // 右孩子不为空,递归判断
if ((retval = insert(tree, &bitree_right(*node), data, balanced))
!= 0) { // 插入失败,返回
return retval; // -1
}
}
/***********************************************************************
* *
* Ensure that the tree remains balanced. *
* *
***********************************************************************/
if (!(*balanced)) { // 不平衡,插入的位置是叶子节点的孩子时,可能不平衡
switch (((AvlNode *)bitree_data(*node))->factor) {
case AVL_LFT_HEAVY: // -1
// 插入之前,左孩子不为空,插入右孩子之后,不改变树的整体平衡性
((AvlNode *)bitree_data(*node))->factor = AVL_BALANCED; // 0
*balanced = 1; // 整体平衡
break;
case AVL_BALANCED: // 0
// 左孩子为空,右孩子不为空
((AvlNode *)bitree_data(*node))->factor = AVL_RGT_HEAVY; // -1,有可能改变原始树的平衡性
break;
case AVL_RGT_HEAVY: // 这种情况不可能出现在递归的末尾,即插入的结点的父节点身上
// 当从最后一层递归返回时,判断最近的平衡因子可能为+-2的结点
rotate_right(node); // 旋转之后
*balanced = 1; // 整体为平衡
}
}
} /* if (cmpval > 0) */
else { // 插入数据重复
/***********************************************************************
* *
* Handle finding a copy of the data. *
* *
***********************************************************************/
if (!((AvlNode *)bitree_data(*node))->hidden) { // 如果这个数已经存在于树中
/********************************************************************
* *
* Do nothing since the data is in the tree and not hidden. *
* *
********************************************************************/
return 1;
}
else {
/********************************************************************
* *
* Insert the new data and mark it as not hidden. *
* *
********************************************************************/
if (tree->destroy != NULL) {
/*****************************************************************
* *
* Destroy the hidden data since it is being replaced. *
* *
*****************************************************************/
// 删除该位置原始的数据,赋值即可
tree->destroy(((AvlNode *)bitree_data(*node))->data);
}
((AvlNode *)bitree_data(*node))->data = (void *)data; // 赋值
((AvlNode *)bitree_data(*node))->hidden = 0; // 显示
/********************************************************************
* *
* Do not rebalance because the tree structure is unchanged. *
* *
********************************************************************/
*balanced = 1; // 整体平衡
}
}
}
return 0;
}
/*****************************************************************************
* *
* --------------------------------- hide --------------------------------- *
* *
*****************************************************************************/
static int hide(BisTree *tree, BiTreeNode *node, const void *data) {
int cmpval, // 比较大小
retval; // 返回值
if (bitree_is_eob(node)) { // 结点为空,返回
/**************************************************************************
* *
* Return that the data was not found. *
* *
**************************************************************************/
return -1;
}
cmpval = tree->compare(data, ((AvlNode *)bitree_data(node))->data); // 比较大小
if (cmpval < 0) { // 左子树查找
/**************************************************************************
* *
* Move to the left. *
* *
**************************************************************************/
retval = hide(tree, bitree_left(node), data);
}
else if (cmpval > 0) { // 右子树查找
/**************************************************************************
* *
* Move to the right. *
* *
**************************************************************************/
retval = hide(tree, bitree_right(node), data);
}
else { // 找到该值
/**************************************************************************
* *
* Mark the node as hidden. *
* *
**************************************************************************/
((AvlNode *)bitree_data(node))->hidden = 1; // 隐藏该结点
retval = 0;
}
return retval;
}
/*****************************************************************************
* *
* -------------------------------- lookup -------------------------------- *
* *
*****************************************************************************/
static int lookup(BisTree *tree, BiTreeNode *node, void **data) {
// 从node开始查找数据
int cmpval, // 比较
retval; // 返回值
if (bitree_is_eob(node)) { // 为空返回
/**************************************************************************
* *
* Return that the data was not found. *
* *
**************************************************************************/
return -1;
}
cmpval = tree->compare(*data, ((AvlNode *)bitree_data(node))->data); // 比较大小标志
if (cmpval < 0) { // 转向左子树
/**************************************************************************
* *
* Move to the left. *
* *
**************************************************************************/
retval = lookup(tree, bitree_left(node), data); // 递归查找
}
else if (cmpval > 0) { // 转向右子树
/**************************************************************************
* *
* Move to the right. *
* *
**************************************************************************/
retval = lookup(tree, bitree_right(node), data); // 递归查找
}
else {
if (!((AvlNode *)bitree_data(node))->hidden) { // 结点没有被隐藏
/***********************************************************************
* *
* Pass back the data from the tree. *
* *
***********************************************************************/
*data = ((AvlNode *)bitree_data(node))->data; // 传参
retval = 0;
}
else { // 该数据不在该树中
/***********************************************************************
* *
* Return that the data was not found. *
* *
***********************************************************************/
return -1;
}
}
return retval;
}
/*****************************************************************************
* *
* ----------------------------- bistree_init ----------------------------- *
* *
*****************************************************************************/
void bistree_init(BisTree *tree, int (*compare)(const void *key1, const void
*key2), void (*destroy)(void *data)) {
/*****************************************************************************
* *
* Initialize the tree. *
* *
*****************************************************************************/
bitree_init(tree, destroy);
tree->compare = compare;
return;
}
/*****************************************************************************
* *
* ---------------------------- bistree_destroy --------------------------- *
* *
*****************************************************************************/
void bistree_destroy(BisTree *tree) {
/*****************************************************************************
* *
* Destroy all nodes in the tree. *
* *
*****************************************************************************/
destroy_left(tree, NULL);
/*****************************************************************************
* *
* No operations are allowed now, but clear the structure as a precaution. *
* *
*****************************************************************************/
memset(tree, 0, sizeof(BisTree));
return;
}
/*****************************************************************************
* *
* ---------------------------- bistree_insert ---------------------------- *
* *
*****************************************************************************/
int bistree_insert(BisTree *tree, const void *data) {
int balanced = 0;
return insert(tree, &bitree_root(tree), data, &balanced);
}
/*****************************************************************************
* *
* ---------------------------- bistree_remove ---------------------------- *
* *
*****************************************************************************/
int bistree_remove(BisTree *tree, const void *data) {
return hide(tree, bitree_root(tree), data);
}
/*****************************************************************************
* *
* ---------------------------- bistree_lookup ---------------------------- *
* *
*****************************************************************************/
int bistree_lookup(BisTree *tree, void **data) {
return lookup(tree, bitree_root(tree), data);
}
(3)ex-1.c
/*****************************************************************************
* *
* ex-1.c *
* ====== *
* *
* Description: Illustrates using a binary tree (see Chapter 9). *
* *
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "bitree.h"
#include "traverse.h"
/*****************************************************************************
* *
* ---------------------------- print_preorder ---------------------------- *
* *
*****************************************************************************/
static void print_preorder(const BiTreeNode *node) {
/*****************************************************************************
* *
* Display the binary tree rooted at the specified node in preorder. *
* *
*****************************************************************************/
if (!bitree_is_eob(node)) {
fprintf(stdout, "Node=%03d\n", *(int *)bitree_data(node));
if (!bitree_is_eob(bitree_left(node)))
print_preorder(bitree_left(node));
if (!bitree_is_eob(bitree_right(node)))
print_preorder(bitree_right(node));
}
return;
}
/*****************************************************************************
* *
* ----------------------------- print_inorder ---------------------------- *
* *
*****************************************************************************/
static void print_inorder(const BiTreeNode *node) {
/*****************************************************************************
* *
* Display the binary tree rooted at the specified node in inorder. *
* *
*****************************************************************************/
if (!bitree_is_eob(node)) {
if (!bitree_is_eob(bitree_left(node)))
print_inorder(bitree_left(node));
fprintf(stdout, "Node=%03d\n", *(int *)bitree_data(node));
if (!bitree_is_eob(bitree_right(node)))
print_inorder(bitree_right(node));
}
return;
}
/*****************************************************************************
* *
* ---------------------------- print_postorder --------------------------- *
* *
*****************************************************************************/
static void print_postorder(const BiTreeNode *node) {
/*****************************************************************************
* *
* Display the binary tree rooted at the specified node in postorder. *
* *
*****************************************************************************/
if (!bitree_is_eob(node)) {
if (!bitree_is_eob(bitree_left(node)))
print_postorder(bitree_left(node));
if (!bitree_is_eob(bitree_right(node)))
print_postorder(bitree_right(node));
fprintf(stdout, "Node=%03d\n", *(int *)bitree_data(node));
}
return;
}
/*****************************************************************************
* *
* ------------------------------ insert_int ------------------------------ *
* *
*****************************************************************************/
static int insert_int(BiTree *tree, int i) {
BiTreeNode *node,
*prev;
int direction,
*data;
/*****************************************************************************
* *
* Insert i assuming a binary tree organized as a binary search tree. *
* *
*****************************************************************************/
node = tree->root;
direction = 0;
while (!bitree_is_eob(node)) {
prev = node;
if (i == *(int *)bitree_data(node)) {
return -1;
}
else if (i < *(int *)bitree_data(node)) {
node = bitree_left(node);
direction = 1;
}
else {
node = bitree_right(node);
direction = 2;
}
}
if ((data = (int *)malloc(sizeof(int))) == NULL)
return -1;
*data = i;
if (direction == 0)
return bitree_ins_left(tree, NULL, data);
if (direction == 1)
return bitree_ins_left(tree, prev, data);
if (direction == 2)
return bitree_ins_right(tree, prev, data);
return -1;
}
/*****************************************************************************
* *
* ------------------------------ search_int ------------------------------ *
* *
*****************************************************************************/
static BiTreeNode *search_int(BiTree *tree, int i) {
BiTreeNode *node;
/*****************************************************************************
* *
* Look up i assuming a binary tree organized as a binary search tree. *
* *
*****************************************************************************/
node = bitree_root(tree);
while (!bitree_is_eob(node)) {
if (i == *(int *)bitree_data(node)) {
return node;
}
else if (i < *(int *)bitree_data(node)) {
node = bitree_left(node);
}
else {
node = bitree_right(node);
}
}
return NULL;
}
/*****************************************************************************
* *
* --------------------------------- main --------------------------------- *
* *
*****************************************************************************/
int main(int argc, char **argv) {
BiTree tree;
BiTreeNode *node;
int i;
/*****************************************************************************
* *
* Initialize the binary tree. *
* *
*****************************************************************************/
bitree_init(&tree, free);
/*****************************************************************************
* *
* Perform some binary tree operations. *
* *
*****************************************************************************/
fprintf(stdout, "Inserting some nodes\n");
if (insert_int(&tree, 20) != 0)
return 1;
if (insert_int(&tree, 10) != 0)
return 1;
if (insert_int(&tree, 30) != 0)
return 1;
if (insert_int(&tree, 15) != 0)
return 1;
if (insert_int(&tree, 25) != 0)
return 1;
if (insert_int(&tree, 70) != 0)
return 1;
if (insert_int(&tree, 80) != 0)
return 1;
if (insert_int(&tree, 23) != 0)
return 1;
if (insert_int(&tree, 26) != 0)
return 1;
if (insert_int(&tree, 5) != 0)
return 1;
fprintf(stdout, "Tree size is %d\n", bitree_size(&tree));
fprintf(stdout, "(Preorder traversal)\n");
print_preorder(bitree_root(&tree));
i = 30;
if ((node = search_int(&tree, i)) == NULL) {
fprintf(stdout, "Could not find %03d\n", i);
}
else {
fprintf(stdout, "Found %03d...Removing the left tree below it\n", i);
bitree_rem_left(&tree, node);
fprintf(stdout, "Tree size is %d\n", bitree_size(&tree));
fprintf(stdout, "(Preorder traversal)\n");
print_preorder(bitree_root(&tree));
}
i = 99;
if ((node = search_int(&tree, i)) == NULL) {
fprintf(stdout, "Could not find %03d\n", i);
}
else {
fprintf(stdout, "Found %03d...Removing the right tree below it\n", i);
bitree_rem_right(&tree, node);
fprintf(stdout, "Tree size is %d\n", bitree_size(&tree));
fprintf(stdout, "(Preorder traversal)\n");
print_preorder(bitree_root(&tree));
}
i = 20;
if ((node = search_int(&tree, i)) == NULL) {
fprintf(stdout, "Could not find %03d\n", i);
}
else {
fprintf(stdout, "Found %03d...Removing the right tree below it\n", i);
bitree_rem_right(&tree, node);
fprintf(stdout, "Tree size is %d\n", bitree_size(&tree));
fprintf(stdout, "(Preorder traversal)\n");
print_preorder(bitree_root(&tree));
}
i = bitree_is_leaf(bitree_root(&tree));
fprintf(stdout, "Testing bitree_is_leaf...Value=%d (0=OK)\n", i);
i = bitree_is_leaf(bitree_left((bitree_root(&tree))));
fprintf(stdout, "Testing bitree_is_leaf...Value=%d (0=OK)\n", i);
i = bitree_is_leaf(bitree_left(bitree_left((bitree_root(&tree)))));
fprintf(stdout, "Testing bitree_is_leaf...Value=%d (1=OK)\n", i);
i = bitree_is_leaf(bitree_right(bitree_left((bitree_root(&tree)))));
fprintf(stdout, "Testing bitree_is_leaf...Value=%d (1=OK)\n", i);
fprintf(stdout, "Inserting some nodes\n");
if (insert_int(&tree, 55) != 0)
return 1;
if (insert_int(&tree, 44) != 0)
return 1;
if (insert_int(&tree, 77) != 0)
return 1;
if (insert_int(&tree, 11) != 0)
return 1;
fprintf(stdout, "Tree size is %d\n", bitree_size(&tree));
fprintf(stdout, "(Preorder traversal)\n");
print_preorder(bitree_root(&tree));
fprintf(stdout, "(Inorder traversal)\n");
print_inorder(bitree_root(&tree));
fprintf(stdout, "(Postorder traversal)\n");
print_postorder(bitree_root(&tree));
/*****************************************************************************
* *
* Destroy the binary tree. *
* *
*****************************************************************************/
fprintf(stdout, "Destroying the tree\n");
bitree_destroy(&tree);
return 0;
}