Mastering Algorithms with C(C语言bistree)

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

}

 

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 游动-白 设计师: 上身试试
应支付0元
点击重新获取
扫码支付

支付成功即可阅读