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;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
There are many books on data structures and algorithms, including some with useful libraries of C functions. Mastering Algorithms with C offers you a unique combination of theoretical background and working code. With robust solutions for everyday programming tasks, this book avoids the abstract style of most classic data structures and algorithms texts, but still provides all of the information you need to understand the purpose and use of common programming techniques. Implementations, as well as interesting, real-world examples of each data structure and algorithm, are included. Using both a programming style and a writing style that are exceptionally clean, Kyle Loudon shows you how to use such essential data structures as lists, stacks, queues, sets, trees, heaps, priority queues, and graphs. He explains how to use algorithms for sorting, searching, numerical analysis, data compression, data encryption, common graph problems, and computational geometry. And he describes the relative efficiency of all implementations. The compression and encryption chapters not only give you working code for reasonably efficient solutions, they offer explanations of concepts in an approachable manner for people who never have had the time or expertise to study them in depth. Anyone with a basic understanding of the C language can use this book. In order to provide maintainable and extendible code, an extra level of abstraction (such as pointers to functions) is used in examples where appropriate. Understanding that these techniques may be unfamiliar to some programmers, Loudon explains them clearly in the introductory chapters. Contents include: Pointers Recursion Analysis of algorithms Data structures (lists, stacks, queues, sets, hash tables, trees, heaps, priority queues, graphs) Sorting and searching Numerical methods Data compression Data encryption Graph algorithms Geometric algorithms
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值