Beispiel #1
0
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;

}
Beispiel #2
0
static void preorder_tree(const BiTreeNode *node) {

/*****************************************************************************
*                                                                            *
*  Display the binary search tree rooted at the specified node.              *
*                                                                            *
*****************************************************************************/

if (!bitree_is_eob(node)) {

   fprintf(stdout, "Node=%s, %+2d, hidden=%d\n", (char *)((AvlNode *)
      bitree_data(node))->data, ((AvlNode *)bitree_data(node))->factor,
      ((AvlNode *)bitree_data(node))->hidden);

   if (!bitree_is_eob(bitree_left(node)))
      preorder_tree(bitree_left(node));

   if (!bitree_is_eob(bitree_right(node)))
      preorder_tree(bitree_right(node));

}

return;

}
Beispiel #3
0
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;
}
Beispiel #4
0
static void build_table(BiTreeNode *node, unsigned short code, unsigned char
   size, HuffCode *table) {

if (!bitree_is_eob(node)) {

   if (!bitree_is_eob(bitree_left(node))) {

      /***********************************************************************
      *                                                                      *
      *  Move to the left and append 0 to the current code.                  *
      *                                                                      *
      ***********************************************************************/

      build_table(bitree_left(node), code << 1, size + 1, table);

   }

   if (!bitree_is_eob(bitree_right(node))) {

      /***********************************************************************
      *                                                                      *
      *  Move to the right and append 1 to the current code.                 *
      *                                                                      *
      ***********************************************************************/

      build_table(bitree_right(node), (code << 1) | 0x0001, size + 1, table);

   }

   if (bitree_is_eob(bitree_left(node))&&bitree_is_eob(bitree_right(node))) {

      /***********************************************************************
      *                                                                      *
      *  Ensure that the current code is in big-endian format.               *
      *                                                                      *
      ***********************************************************************/

      code = htons(code);

      /***********************************************************************
      *                                                                      *
      *  Assign the current code to the symbol in the leaf node.             *
      *                                                                      *
      ***********************************************************************/

      table[((HuffNode *)bitree_data(node))->symbol].used = 1;
      table[((HuffNode *)bitree_data(node))->symbol].code = code;
      table[((HuffNode *)bitree_data(node))->symbol].size = size;

   }

}

return;

}
Beispiel #5
0
void
report1_format(const BiTreeNode *node) {

	printf("%s\t\t",
			(char *)((TNode *)((AvlNode *)
			bitree_data(node))->data)->vname);
	print_nodechildren(node);
	print_lineno((List *)((TNode *)((AvlNode *)
			bitree_data(node))->data)->appear);
	return;
};
Beispiel #6
0
void
report2_format(const BiTreeNode *node) {
	printf("%s		%d		",
			(char *)((TNode *)((AvlNode *)
			bitree_data(node))->data)->vname, 
			list_size((List *)((TNode *)((AvlNode *)
			bitree_data(node))->data)->appear)
			);
	print_formatedlist((List *)((TNode *)((AvlNode *)
				bitree_data(node))->data)->appear);
	return;
};
Beispiel #7
0
int preorder (const BiTreeNode *node, List *list)
{
    if (!bitree_is_eob(node)) {

        // problem with insert data into list
        if (list_ins_next(list, list_tail(list), bitree_data(node)) != 0) {
            return -1;
        }

        // traverse the non-NULL left node
        if (!bitree_is_eob(bitree_left(node))) {
            if (preorder(bitree_left(node), list) != 0) {
                return -1;
            }
        }

        // traverse the non_NULL right node
        if (!bitree_is_eob(bitree_right(node))) {
            if (preorder(bitree_right(node), list) != 0) {
                return -1;
            }
        }
    }

    return 0;
}
Beispiel #8
0
void
print_nodechildren(const BiTreeNode *node) {

	printf("%s\t\t\t%s\t\t\t",
		((!bitree_is_eob(bitree_right(node))) ? 
		((char *)((TNode *)((AvlNode *)
		bitree_data(bitree_right(node)))->data)->vname) :
		"NIL"),

		((!bitree_is_eob(bitree_left(node))) ? 
		((char *)((TNode *)((AvlNode *)
		bitree_data(bitree_left(node)))->data)->vname) :
		"NIL")
	);
	return;
};
Beispiel #9
0
int postorder(const BiTreeNode *node, List *list) {

/*****************************************************************************
*                                                                            *
*  Load the list with a postorder listing of the tree.                       *
*                                                                            *
*****************************************************************************/

if (!bitree_is_eob(node)) {

   if (!bitree_is_eob(bitree_left(node)))
      if (postorder(bitree_left(node), list) != 0)
         return -1;

   if (!bitree_is_eob(bitree_right(node)))
      if (postorder(bitree_right(node), list) != 0)
         return -1;

   if (list_ins_next(list, list_tail(list), bitree_data(node)) != 0)
      return -1;

}

return 0;

}
/**
 * 前序遍历二叉树
 */
int preorder(const BiTreeNode *node, List *list) {

    if (!bitree_is_eob(node)) {
        if (list_ins_next(list, list_tail(list), bitree_data(node)) != 0) {
            printf("%s\n", "preorder() insert node into list fail.");
            return -1;
        }

        //不是没有下级节点的节点
        if (!bitree_is_eob(bitree_left(node))) {
            if (preorder(bitree_left(node), list) != 0) { //递归调用
                printf("%s\n", "preorder() left tree order fail.");
                return -1;
            }

            if(!bitree_is_eob(bitree_right(node))) {
            	if(preorder(bitree_right(node), list) != 0) {//递归调用
                    printf("%s\n", "preorder() right tree order end.");
            		return -1;
            	}
            }
        }
    }

    return 0;
}
Beispiel #11
0
int
postorder(const BiTreeNode *node) {
	if (!bitree_is_eob(node)) {
		if (!bitree_is_eob(bitree_left(node)))
			if(postorder(bitree_left(node)) != 0)
				return(-1);

		if (!bitree_is_eob(bitree_right(node)))
			if(postorder(bitree_right(node)) != 0)
				return(-1);

fprintf(stdout, "Node=%s (size: %d), %+2d, hidden=%d\n", 
   (char *)((TNode *)((AvlNode *)bitree_data(node))->data)->vname, 
   list_size((List *)((TNode *)((AvlNode *)bitree_data(node))->data)->appear), 
   ((AvlNode *)bitree_data(node))->factor,
   ((AvlNode *)bitree_data(node))->hidden);
	}
	return(0);
}
static int lookup (AvlTree *tree, BiTreeNode *node, void **data) {
  int cmpval, retval = -1;
  if (bitree_is_eob(tree))
    return retval;
  cmpval = tree->compare(*data, ((AvlTreeNode *)bitree_data(node))->data);
  if (cmpval < 0) {
    retval = lookup(tree, bitree_left(node), data);
  } else if (cmpval > 0) {
    retval = lookup(tree, bitree_right(node), data);
  } else {
    if (!((AvlTreeNode *)bitree_data(node))->hidden) {
      *data = ((AvlTreeNode *)bitree_data(node))->data;
      retval = 0;
    } else {
      retval = -1;
    }
  }
  return retval;
}
static int compare_freq(const void *tree1, const void *tree2)
{

	HuffNode *root1, *root2;

/*****************************************************************************
*  Compare the frequencies stored in the root nodes of two binary trees.     *
*****************************************************************************/

	root1 = (HuffNode *) bitree_data(bitree_root((const BiTree *)tree1));
	root2 = (HuffNode *) bitree_data(bitree_root((const BiTree *)tree2));

	if (root1->freq < root2->freq)
		return 1;
	else if (root1->freq > root2->freq)
		return -1;
	else
		return 0;

}
Beispiel #14
0
static int
lookup (BisTree *tree, BiTreeNode *node, 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 = 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;
}
Beispiel #15
0
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;

}
Beispiel #16
0
/* 后序遍历 */
int postorder(const BiTreeNode *node, List *list) {
  if (!bitree_is_eob(node)) {
    /* 左 */
    if (!bitree_is_eob(bitree_left(node)))
      if (postorder(bitree_left(node), list) != 0)
        return -1;
    /* 右 */
    if (!bitree_is_eob(bitree_right(node)))
      if (postorder(bitree_right(node), list) != 0)
        return -1;
    /* 根 */
    if (list_ins_next(list, list_tail(list), bitree_data(node)) != 0)
      return -1;
  }
  return 0;
}
int inorder(const BiTreeNode *node, List *list)
{
	if(!bitree_is_eob(node))
	{
		if(!bitree_is_eob(bitree_left(node)))
		{
			if(inorder(bitree_left(node), list) != 0)
				return -1;
		}

		if(list_ins_next(list, list_tail(list), bitree_data(node)) != 0)
			return -1;

		if(!bitree_is_eob(bitree_right(node)))
		{
			if(inorder(bitree_right(node), list) != 0)
				return -1;
		}
	}
	return 0;
}
Beispiel #18
0
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;

}
/**
 * 后序遍历二叉树
 */
int postorder(const BiTreeNode *node, List *list){

	if(!bitree_is_eob(node)){
		if(!bitree_is_eob(bitree_left(node))){
			if(inorder(bitree_left(node), list) != 0){
				printf("%s\n","postorder() left tree order end");
				return -1;
			}
		}
		if(!bitree_is_eob(bitree_right(node))){
			if(inorder(bitree_right(node), list) != 0){
				printf("%s\n", "postorder() right tree order end");
				return -1;
			}
		}
		if(list_ins_next(list, list_tail(list), bitree_data(node)) != 0){
			printf("%s\n", "postorder() add node to list fail.");
			return -1;
		}
	}

    return 0;
}
Beispiel #20
0
static int
insert (BisTree *tree, BiTreeNode **node, const void *data, int *balanced)
{
  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;
      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;
              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;
                }
            }

          /* Ensure that the tree remains balanced.  */
          if (!(*balanced))
            {
              switch (((AvlNode *) bitree_data (*node))->factor)
                {
                  case AVL_LFT_HEAVY:
                      rotate_left (node);
                      *balanced = 1;
                      break;
                  case AVL_BALANCED:
                      ((AvlNode *) bitree_data (*node))->factor = AVL_LFT_HEAVY;
                      break;
                  case AVL_RGT_HEAVY:
                      ((AvlNode *) bitree_data (*node))->factor = AVL_BALANCED;
                      *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;
              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;
                }
            }

          /* Ensure that the tree remains balanced.  */
          if (!(*balanced))
            {
              switch (((AvlNode *) bitree_data (*node))->factor)
                {
                  case AVL_LFT_HEAVY:
                      ((AvlNode *) bitree_data (*node))->factor = AVL_BALANCED;
                      *balanced = 1;
                      break;

                  case AVL_BALANCED:
                      ((AvlNode *) bitree_data (*node))->factor = AVL_RGT_HEAVY;
                      break;
                  case AVL_RGT_HEAVY:
                      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;
}
static void rotate_right(BiTreeNode **node) {
  BiTreeNode *right, *grandchild;
  right = bitree_right(*node);
  // RR rotate
  if (((AvlTreeNode *)bitree_data(right))->factor == AVL_RIGHT_HEAVY) {
    bitree_right(*node) = bitree_left(right);
    bitree_left(right) = *node;
    ((AvlTreeNode *)bitree_data(*node))->factor = AVL_BALANCED;
    ((AvlTreeNode *)bitree_data(right))->factor = AVL_BALANCED;
    *node = right;
  // RL rotate
  } else {
    grandchild = bitree_left(right);
    bitree_left(right) = bitree_right(grandchild);
    bitree_right(grandchild) = right;
    bitree_right(*node) = bitree_left(grandchild);
    bitree_left(grandchild) = *node;
    switch (((AvlTreeNode *)bitree_data(grandchild))->factor) {
      case AVL_LEFT_HEAVY:
        ((AvlTreeNode *)bitree_data(*node))->factor = AVL_BALANCED;
        ((AvlTreeNode *)bitree_data(right))->factor = AVL_RIGHT_HEAVY;
        break;
      case AVL_BALANCED:
        ((AvlTreeNode *)bitree_data(*node))->factor = AVL_BALANCED;
        ((AvlTreeNode *)bitree_data(right))->factor = AVL_BALANCED;
        break;
      case AVL_RIGHT_HEAVY:
        ((AvlTreeNode *)bitree_data(*node))->factor = AVL_LEFT_HEAVY;
        ((AvlTreeNode *)bitree_data(right))->factor = AVL_BALANCED;
        break;
    }
    ((AvlTreeNode *)bitree_data(grandchild))->factor = AVL_BALANCED;
    *node = grandchild;
  }
  return;
}
static int insert(Bitree *tree, BiTreeNode **node, const void *data, int *balanced) {
  AvlTreeNode *avlnode;
  int result, compare;
  if (bitree_is_eob(*node)) {
    if ((avlnode = (AvlTreeNode *)malloc(sizeof(AvlTreeNode))) == NULL) 
      return -1;
    avlnode->factor = 0;
    avlnode->data = (void *)data;
    avlnode->hidden = 0;
    return bitree_insert_left(tree, *node, avlnode);
  } else {
    compare = tree->compare(data, ((AvlTreeNode *)bitree_data(*node))->data);

    if (compare < 0) {

      if (bitree_is_eob(bitree_left(*node))) {
        if ((avlnode = (AvlTreeNode *)malloc(sizeof(AvlTreeNode))) == NULL) 
          return -1;
        avlnode->factor = 0;
        avlnode->data = (void *)data;
        avlnode->hidden = 0;
        if (bitree_insert_left(tree, *node, avlnode) != 0)
          return -1;
        *balanced = 0;
      } else {
        if ((result = insert(tree, &bitree_left(*node), data, balanced)) != 0) {
          return result;
        }
      }

      if (!(*balanced)) {
        switch (((AvlTreeNode *)bitree_data(*node))->factor) {
          case AVL_LEFT_HEAVY:
            rotate_left(node);
            *balanced = 1;
            break;
          case AVL_BALANCED:
            ((AvlTreeNode *)bitree_data(*node))->factor = AVL_LEFT_HEAVY;
            break;
          case AVL_RIGHT_HEAVY:
            ((AvlTreeNode *)bitree_data(*node))->factor = AVL_BALANCED;
            *balanced = 1;
            break;
        }
      }

    } else if (compare > 0) {
      
      if (bitree_is_eob(bitree_right(*node))) {
        if ((avlnode = (AvlTreeNode *)malloc(sizeof(AvlTreeNode))) == NULL) 
          return -1;
        avlnode->factor = 0;
        avlnode->data = (void *)data;
        avlnode->hidden = 0;
        if (bitree_insert_right(tree, *node, avlnode) != 0)
          return -1;
        *balanced = 0;
      } else {
        if ((result = insert(tree, &bitree_right(*node), data, balanced)) != 0) {
          return result;
        }
      }

      if (!(*balanced)) {
        switch (((AvlTreeNode *)bitree_data(*node))->factor) {
          case AVL_LEFT_HEAVY:
            ((AvlTreeNode *)bitree_data(*node))->factor = AVL_BALANCED;
            *balanced = 1;
            break;
          case AVL_BALANCED:
            ((AvlTreeNode *)bitree_data(*node))->factor = AVL_RIGHT_HEAVY;
            break;
          case AVL_RIGHT_HEAVY:
            rotate_right(node);
            *balanced = 1;
            break;
        }
      }

    } else {
      if (!((AvlTreeNode *)bitree_data(*node))->hidden) {
        return 1;
      } else {
        if (tree->destory != NULL)
          tree->destory(((AvlTreeNode *)bitree_data(*node))->data);
        ((AvlTreeNode *)bitree_data(*node))->data = (void *)data;
        ((AvlTreeNode *)bitree_data(*node))->hidden = 0;
        *balanced = 1;
      }
    }
  }
  return 0;
}
Beispiel #23
0
static int build_tree(int *freqs, BiTree **tree) {

BiTree             *init,
                   *merge,
                   *left,
                   *right;

PQueue             pqueue;

HuffNode           *data;

int                size,
                   c;

/*****************************************************************************
*                                                                            *
*  Initialize the priority queue of binary trees.                            *
*                                                                            *
*****************************************************************************/

*tree = NULL;

pqueue_init(&pqueue, compare_freq, destroy_tree);

for (c = 0; c <= UCHAR_MAX; c++) {

   if (freqs[c] != 0) {

      /***********************************************************************
      *                                                                      *
      *  Set up a binary tree for the current symbol and its frequency.      *
      *                                                                      *
      ***********************************************************************/

      if ((init = (BiTree *)malloc(sizeof(BiTree))) == NULL) {

         pqueue_destroy(&pqueue);
         return -1;

      }

      bitree_init(init, free);

      if ((data = (HuffNode *)malloc(sizeof(HuffNode))) == NULL) {

         pqueue_destroy(&pqueue);
         return -1;

      }

      data->symbol = c;
      data->freq = freqs[c];

      if (bitree_ins_left(init, NULL, data) != 0) {

         free(data);
         bitree_destroy(init);
         free(init);
         pqueue_destroy(&pqueue);
         return -1;

      }

      /***********************************************************************
      *                                                                      *
      *  Insert the binary tree into the priority queue.                     *
      *                                                                      *
      ***********************************************************************/

      if (pqueue_insert(&pqueue, init) != 0) {

         bitree_destroy(init);
         free(init);
         pqueue_destroy(&pqueue);
         return -1;

      }

   }

}

/*****************************************************************************
*                                                                            *
*  Build a Huffman tree by merging trees in the priority queue.              *
*                                                                            *
*****************************************************************************/

size = pqueue_size(&pqueue);

for (c = 1; c <= size - 1; c++) {

   /**************************************************************************
   *                                                                         *
   *  Allocate storage for the next merged tree.                             *
   *                                                                         *
   **************************************************************************/

   if ((merge = (BiTree *)malloc(sizeof(BiTree))) == NULL) {

      pqueue_destroy(&pqueue);
      return -1;

   }

   /**************************************************************************
   *                                                                         *
   *  Extract the two trees whose root nodes have the smallest frequencies.  *
   *                                                                         *
   **************************************************************************/

   if (pqueue_extract(&pqueue, (void **)&left) != 0) {

      pqueue_destroy(&pqueue);
      free(merge);
      return -1;

   }

   if (pqueue_extract(&pqueue, (void **)&right) != 0) {

      pqueue_destroy(&pqueue);
      free(merge);
      return -1;

   }

   /**************************************************************************
   *                                                                         *
   *  Allocate storage for the data in the root node of the merged tree.     *
   *                                                                         *
   **************************************************************************/

   if ((data = (HuffNode *)malloc(sizeof(HuffNode))) == NULL) {

      pqueue_destroy(&pqueue);
      free(merge);
      return -1;

   }

   memset(data, 0, sizeof(HuffNode));

   /**************************************************************************
   *                                                                         *
   *  Sum the frequencies in the root nodes of the trees being merged.       *
   *                                                                         *
   **************************************************************************/

   data->freq = ((HuffNode *)bitree_data(bitree_root(left)))->freq +
      ((HuffNode *)bitree_data(bitree_root(right)))->freq;

   /**************************************************************************
   *                                                                         *
   *  Merge the two trees.                                                   *
   *                                                                         *
   **************************************************************************/

   if (bitree_merge(merge, left, right, data) != 0) {

      pqueue_destroy(&pqueue);
      free(merge);
      return -1;

   }

   /**************************************************************************
   *                                                                         *
   *  Insert the merged tree into the priority queue and free the others.    *
   *                                                                         *
   **************************************************************************/

   if (pqueue_insert(&pqueue, merge) != 0) {

      pqueue_destroy(&pqueue);
      bitree_destroy(merge);
      free(merge);
      return -1;

   }

   free(left);
   free(right);

}

/*****************************************************************************
*                                                                            *
*  The last tree in the priority queue is the Huffman tree.                  *
*                                                                            *
*****************************************************************************/

if (pqueue_extract(&pqueue, (void **)tree) != 0) {

   pqueue_destroy(&pqueue);
   return -1;

   }

else {

   pqueue_destroy(&pqueue);

}

return 0;

}
Beispiel #24
0
int huffman_uncompress(const unsigned char *compressed, unsigned char
   **original) {

BiTree             *tree;
BiTreeNode         *node;

int                freqs[UCHAR_MAX + 1],
                   hsize,
                   size,
                   ipos,
                   opos,
                   state,
                   c;

unsigned char      *orig,
                   *temp;

/*****************************************************************************
*                                                                            *
*  Initially there is no buffer of original data.                            *
*                                                                            *
*****************************************************************************/

*original = orig = NULL;

/*****************************************************************************
*                                                                            *
*  Get the header information from the buffer of compressed data.            *
*                                                                            *
*****************************************************************************/

hsize = sizeof(int) + (UCHAR_MAX + 1);
memcpy(&size, compressed, sizeof(int));

for (c = 0; c <= UCHAR_MAX; c++)
   freqs[c] = compressed[sizeof(int) + c];

/*****************************************************************************
*                                                                            *
*  Rebuild the Huffman tree used previously to compress the data.            *
*                                                                            *
*****************************************************************************/

if (build_tree(freqs, &tree) != 0)
   return -1;

/*****************************************************************************
*                                                                            *
*  Uncompress the data.                                                      *
*                                                                            *
*****************************************************************************/

ipos = hsize * 8;
opos = 0;
node = bitree_root(tree);

while (opos < size) {

   /**************************************************************************
   *                                                                         *
   *  Get the next bit in the compressed data.                               *
   *                                                                         *
   **************************************************************************/

   state = bit_get(compressed, ipos);
   ipos++;

   if (state == 0) {

      /***********************************************************************
      *                                                                      *
      *  Move to the left.                                                   *
      *                                                                      *
      ***********************************************************************/

      if (bitree_is_eob(node) || bitree_is_eob(bitree_left(node))) {

         bitree_destroy(tree);
         free(tree);
         return -1;

         }

      else
         node = bitree_left(node);

      }

   else {

      /***********************************************************************
      *                                                                      *
      *  Move to the right.                                                  *
      *                                                                      *
      ***********************************************************************/

      if (bitree_is_eob(node) || bitree_is_eob(bitree_right(node))) {

         bitree_destroy(tree);
         free(tree);
         return -1;

         }

      else
         node = bitree_right(node);

   }

   if (bitree_is_eob(bitree_left(node))&&bitree_is_eob(bitree_right(node))) {

      /***********************************************************************
      *                                                                      *
      *  Write the symbol in the leaf node to the buffer of original data.   *
      *                                                                      *
      ***********************************************************************/

      if (opos > 0) {

         if ((temp = (unsigned char *)realloc(orig, opos + 1)) == NULL) {

            bitree_destroy(tree);
            free(tree);
            free(orig);
            return -1;

         }

         orig = temp;

         }

      else {

         if ((orig = (unsigned char *)malloc(1)) == NULL) {

            bitree_destroy(tree);
            free(tree);
            return -1;

         }

      }

      orig[opos] = ((HuffNode *)bitree_data(node))->symbol;
      opos++;

      /***********************************************************************
      *                                                                      *
      *  Move back to the top of the tree.                                   *
      *                                                                      *
      ***********************************************************************/

      node = bitree_root(tree);

   }

}

bitree_destroy(tree);
free(tree);

/*****************************************************************************
*                                                                            *
*  Point to the buffer of original data.                                     *
*                                                                            *
*****************************************************************************/

*original = orig;

/*****************************************************************************
*                                                                            *
*  Return the number of bytes in the original data.                          *
*                                                                            *
*****************************************************************************/

return opos;

}
Beispiel #25
0
static void
rotate_left (BiTreeNode **node)
{
  BiTreeNode *left, *grandchild;

  left = bitree_left (*node);
  if (((AvlNode *) bitree_data (left))->factor == AVL_LFT_HEAVY)
    {
      /* Perform an LL rotation.  */
      bitree_left (*node) = bitree_right (left);
      bitree_right (left) = *node;
      ((AvlNode *) bitree_data (*node))->factor = AVL_BALANCED;
      ((AvlNode *) bitree_data (left))->factor = AVL_BALANCED;
      *node = left;
    }
  else
    {
      /* Perform an LR rotation.  */
      grandchild = bitree_right (left);
      bitree_right (left) = bitree_left (grandchild);
      bitree_left (grandchild) = left;
      bitree_left (*node) = bitree_right (grandchild);
      bitree_right (grandchild) = *node;

      switch (((AvlNode *) bitree_data (grandchild))->factor)
        {
          case AVL_LFT_HEAVY:
              ((AvlNode *) bitree_data (*node))->factor = AVL_RGT_HEAVY;
              ((AvlNode *) bitree_data (left))->factor = AVL_BALANCED;
              break;
          case AVL_BALANCED:
              ((AvlNode *) bitree_data (*node))->factor = AVL_BALANCED;
              ((AvlNode *) bitree_data (left))->factor = AVL_BALANCED;
              break;
          case AVL_RGT_HEAVY:
              ((AvlNode *) bitree_data (*node))->factor = AVL_BALANCED;
              ((AvlNode *) bitree_data (left))->factor = AVL_LFT_HEAVY;
              break;
        }

      ((AvlNode *) bitree_data (grandchild))->factor = AVL_BALANCED;
      *node = grandchild;
    }
  return;
}