(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;
}