Esempio n. 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;

}
Esempio n. 2
0
int bitree_merge(BiTree *merge, BiTree *left, BiTree *right, const void
   *data) {

/*****************************************************************************
*                                                                            *
*  Initialize the merged tree.                                               *
*                                                                            *
*****************************************************************************/

bitree_init(merge, left->destroy);

/*****************************************************************************
*                                                                            *
*  Insert the data for the root node of the merged tree.                     *
*                                                                            *
*****************************************************************************/

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

   bitree_destroy(merge);
   return -1;

}

/*****************************************************************************
*                                                                            *
*  Merge the two binary trees into a single binary tree.                     *
*                                                                            *
*****************************************************************************/

bitree_root(merge)->left = bitree_root(left);
bitree_root(merge)->right = bitree_root(right);

/*****************************************************************************
*                                                                            *
*  Adjust the size of the new binary tree.                                   *
*                                                                            *
*****************************************************************************/

merge->size = merge->size + bitree_size(left) + bitree_size(right);

/*****************************************************************************
*                                                                            *
*  Do not let the original trees access the merged nodes.                    *
*                                                                            *
*****************************************************************************/

left->root = NULL;
left->size = 0;
right->root = NULL;
right->size = 0;

return 0;

}
Esempio n. 3
0
int main(void) {
	BiTree * tree;
	char * a[] = {"kobe", "bryant", "james", "jordan", "johnson"};
	List *list;
	ListNode *node;

	tree = (BiTree *) malloc(sizeof(BiTree));
	if (tree == NULL) return -1;

	list = (List *) malloc(sizeof(List));
	if (list == NULL) return -1;

	bitree_init(tree, &data_destroy);
	bitree_ins_left(tree, NULL, a[0]);


	bitree_ins_left(tree, tree->root, a[1]);
	bitree_ins_right(tree, tree->root, a[2]);

	bitree_ins_left(tree, tree->root->left, a[3]);
	bitree_ins_right(tree, tree->root->left, a[4]);

	//list init

	list_init(list, &data_destroy);
	
	postorder(tree->root, list);
	node = list->head;
	
	while(node != NULL) {
		printf("%s\n", (char *) node->data );
		node = node->next;
	}
	

	bitree_destroy(tree);
	list_destroy(list);
	return 0;	
}
Esempio n. 4
0
int main(int argc, char const *argv[])
{
    //create a unbalanced tree
    BiTree * unbalanced_tree = (BiTree*)malloc(sizeof(BiTree));

    bitree_init(unbalanced_tree, NULL);

    int tree_node_index[5];
    for (int i = 0; i < 5; ++i)
    {
        tree_node_index[i] = i;
    }
    BiTreeNode * position = NULL;

    bitree_ins_left(unbalanced_tree, NULL, (void *)&tree_node_index[0]);
    bitree_ins_left(unbalanced_tree, bitree_root(unbalanced_tree), (void *)&tree_node_index[1]);
    position = bitree_root(unbalanced_tree)->left;
    bitree_ins_left(unbalanced_tree, position, (void *)&tree_node_index[2]);
    position = position->left;
    bitree_ins_left(unbalanced_tree, position, (void *)&tree_node_index[3]);
    bitree_ins_right(unbalanced_tree, bitree_root(unbalanced_tree), (void *)&tree_node_index[4]);

    int balance_check_result = check_balance(bitree_root(unbalanced_tree));
    if(balance_check_result < 0)
        printf("unbalanced tree\n");
    else
        printf("balanced tree\n");

    bitree_destroy(unbalanced_tree);
    free(unbalanced_tree);

    //create a balanced tree
    BiTree * balanced_tree = (BiTree *)malloc(sizeof(BiTree));
    bitree_init(balanced_tree, NULL);
    bitree_ins_left(balanced_tree, NULL, (void *)&tree_node_index[0]);
    bitree_ins_left(balanced_tree, bitree_root(balanced_tree), (void *)&tree_node_index[1]);

    position = bitree_root(balanced_tree)->left;

    bitree_ins_left(balanced_tree, position, (void *)&tree_node_index[2]);
    bitree_ins_right(balanced_tree, position, (void *)&tree_node_index[3]);
    bitree_ins_right(balanced_tree, bitree_root(balanced_tree), (void *)&tree_node_index[4]);

    balance_check_result = check_balance(bitree_root(balanced_tree));
    if(balance_check_result < 1)
        printf("unbalanced!\n");
    else
        printf("balanced\n");
    bitree_destroy(balanced_tree);
    free(balanced_tree);    
    return 0;
}
Esempio n. 5
0
struct bitree *build(int n)
{
	int i, *data;
	struct bitree *tree = NULL;
	struct bitree_node *position = NULL;

	tree = (struct bitree *) malloc(sizeof(struct bitree));
	if (!tree)
		return NULL;

	bitree_init(tree, NULL);

	data = (int *) malloc(n * sizeof(int));
	if (!data) {
		goto fail;
	}

	for (i = 0; i <= n/2; i++) {
		data[i] = i + 1;
		if (bitree_ins_left(tree, position, (const void *) &data[i]) != 0)
			goto fail;

		if (!position) {
			if (bitree_root(tree) == NULL)
				goto fail;
			position = bitree_root(tree);
		} else {
			position = position->left;
		}
	}

	position = bitree_root(tree);
	for (i = n/2 + 1; i < n; i++) {
		data[i] = i + 1;
		if (bitree_ins_right(tree, position, (const void *) &data[i]) != 0)
			goto fail;

		position = position->right;
	}

	return tree;

fail:
	free(tree);
	return NULL;
}
Esempio n. 6
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;

}
Esempio n. 7
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;
}