예제 #1
0
/* Examines the binary tree rooted at |node|.
   Zeroes |*okay| if an error occurs.
   Otherwise, does not modify |*okay|.
   Sets |*count| to the number of nodes in that tree,
   including |node| itself if |node != NULL|.
   All the nodes in the tree are verified to be at least |min|
   but no greater than |max|. */
static void
recurse_verify_tree (struct tbst_node *node, int *okay, size_t *count,
                     int min, int max)
{
  int d;                /* Value of this node's data. */
  size_t subcount[2];   /* Number of nodes in subtrees. */

  if (node == NULL)
    {
      *count = 0;
      return;
    }
  d = *(int *) node->tbst_data;

  if (min > max)
    {
      printf (" Parents of node %d constrain it to empty range %d...%d.\n",
              d, min, max);
      *okay = 0;
    }
  else if (d < min || d > max)
    {
      printf (" Node %d is not in range %d...%d implied by its parents.\n",
              d, min, max);
      *okay = 0;
    }

  subcount[0] = subcount[1] = 0;
  if (node->tbst_tag[0] == TBST_CHILD)
    recurse_verify_tree (node->tbst_link[0], okay, &subcount[0], min, d - 1);
  if (node->tbst_tag[1] == TBST_CHILD)
    recurse_verify_tree (node->tbst_link[1], okay, &subcount[1], d + 1, max);
  *count = 1 + subcount[0] + subcount[1];
}
예제 #2
0
/* Examines the binary tree rooted at |node|.
   Zeroes |*okay| if an error occurs.
   Otherwise, does not modify |*okay|.
   Sets |*count| to the number of nodes in that tree,
   including |node| itself if |node != NULL|.
   Sets |*height| to the tree's height.
   All the nodes in the tree are verified to be at least |min|
   but no greater than |max|. */
static void
recurse_verify_tree (struct tavl_node *node, int *okay, size_t *count,
                     int min, int max, int *height)
{
  int d;                /* Value of this node's data. */
  size_t subcount[2];   /* Number of nodes in subtrees. */
  int subheight[2];     /* Heights of subtrees. */

  if (node == NULL)
    {
      *count = 0;
      *height = 0;
      return;
    }
  d = *(int *) node->tavl_data;

  if (min > max)
    {
      printf (" Parents of node %d constrain it to empty range %d...%d.\n",
              d, min, max);
      *okay = 0;
    }
  else if (d < min || d > max)
    {
      printf (" Node %d is not in range %d...%d implied by its parents.\n",
              d, min, max);
      *okay = 0;
    }

  subcount[0] = subcount[1] = 0;
  subheight[0] = subheight[1] = 0;
  if (node->tavl_tag[0] == TAVL_CHILD)
    recurse_verify_tree (node->tavl_link[0], okay, &subcount[0],
                         min, d -  1, &subheight[0]);
  if (node->tavl_tag[1] == TAVL_CHILD)
    recurse_verify_tree (node->tavl_link[1], okay, &subcount[1],
                         d + 1, max, &subheight[1]);
  *count = 1 + subcount[0] + subcount[1];
  *height = 1 + (subheight[0] > subheight[1] ? subheight[0] : subheight[1]);

  if (subheight[1] - subheight[0] != node->tavl_balance)
    {
      printf (" Balance factor of node %d is %d, but should be %d.\n",
              d, node->tavl_balance, subheight[1] - subheight[0]);
      *okay = 0;
    }
  else if (node->tavl_balance < -1 || node->tavl_balance > +1)
    {
      printf (" Balance factor of node %d is %d.\n", d, node->tavl_balance);
      *okay = 0;
    }
}
예제 #3
0
/* Examines the binary tree rooted at |node|.
   Zeroes |*okay| if an error occurs.
   Otherwise, does not modify |*okay|.
   Sets |*count| to the number of nodes in that tree,
   including |node| itself if |node != NULL|.
   All the nodes in the tree are verified to be at least |min|
   but no greater than |max|. */
static void
recurse_verify_tree (struct pbst_node *node, int *okay, size_t *count,
                     int min, int max)
{
    int d;                /* Value of this node's data. */
    size_t subcount[2];   /* Number of nodes in subtrees. */
    int i;

    if (node == NULL)
    {
        *count = 0;
        return;
    }
    d = *(int *) node->pbst_data;

    if (min > max)
    {
        printf (" Parents of node %d constrain it to empty range %d...%d.\n",
                d, min, max);
        *okay = 0;
    }
    else if (d < min || d > max)
    {
        printf (" Node %d is not in range %d...%d implied by its parents.\n",
                d, min, max);
        *okay = 0;
    }

    recurse_verify_tree (node->pbst_link[0], okay, &subcount[0], min, d - 1);
    recurse_verify_tree (node->pbst_link[1], okay, &subcount[1], d + 1, max);
    *count = 1 + subcount[0] + subcount[1];

    for (i = 0; i < 2; i++)
    {
        if (node->pbst_link[i] != NULL
                && node->pbst_link[i]->pbst_parent != node)
        {
            printf (" Node %d has parent %d (should be %d).\n",
                    *(int *) node->pbst_link[i]->pbst_data,
                    (node->pbst_link[i]->pbst_parent != NULL
                     ? *(int *) node->pbst_link[i]->pbst_parent->pbst_data : -1),
                    d);
            *okay = 0;
        }
    }
}
예제 #4
0
/* Checks that |tree| is well-formed
   and verifies that the values in |array[]| are actually in |tree|.
   There must be |n| elements in |array[]| and |tree|.
   Returns nonzero only if no errors detected. */
static int
verify_tree (struct prb_table *tree, int array[], size_t n)
{
  int okay = 1;

  /* Check |tree|'s bst_count against that supplied. */
  if (prb_count (tree) != n)
    {
      printf (" Tree count is %lu, but should be %lu.\n",
              (unsigned long) prb_count (tree), (unsigned long) n);
      okay = 0;
    }

  if (okay)
    {
      if (tree->prb_root != NULL && tree->prb_root->prb_color != PRB_BLACK)
        {
          printf (" Tree's root is not black.\n");
          okay = 0;
        }
    }

  if (okay)
    {
      /* Recursively verify tree structure. */
      size_t count;
      int bh;

      recurse_verify_tree (tree->prb_root, &okay, &count, 0, INT_MAX, &bh);
      if (count != n)
        {
          printf (" Tree has %lu nodes, but should have %lu.\n",
                  (unsigned long) count, (unsigned long) n);
          okay = 0;
        }
    }

  if (okay)
    {
      /* Check that all the values in |array[]| are in |tree|. */
      size_t i;

      for (i = 0; i < n; i++)
        if (prb_find (tree, &array[i]) == NULL)
          {
            printf (" Tree does not contain expected value %d.\n", array[i]);
            okay = 0;
          }
    }

  if (okay)
    {
      /* Check that |prb_t_first()| and |prb_t_next()| work properly. */
      struct prb_traverser trav;
      size_t i;
      int prev = -1;
      int *item;

      for (i = 0, item = prb_t_first (&trav, tree); i < 2 * n && item != NULL;
           i++, item = prb_t_next (&trav))
        {
          if (*item <= prev)
            {
              printf (" Tree out of order: %d follows %d in traversal\n",
                      *item, prev);
              okay = 0;
            }

          prev = *item;
        }

      if (i != n)
        {
          printf (" Tree should have %lu items, but has %lu in traversal\n",
                  (unsigned long) n, (unsigned long) i);
          okay = 0;
        }
    }

  if (okay)
    {
      /* Check that |prb_t_last()| and |prb_t_prev()| work properly. */
      struct prb_traverser trav;
      size_t i;
      int next = INT_MAX;
      int *item;

      for (i = 0, item = prb_t_last (&trav, tree); i < 2 * n && item != NULL;
           i++, item = prb_t_prev (&trav))
        {
          if (*item >= next)
            {
              printf (" Tree out of order: %d precedes %d in traversal\n",
                      *item, next);
              okay = 0;
            }

          next = *item;
        }

      if (i != n)
        {
          printf (" Tree should have %lu items, but has %lu in reverse\n",
                  (unsigned long) n, (unsigned long) i);
          okay = 0;
        }
    }

  if (okay)
    {
      /* Check that |prb_t_init()| works properly. */
      struct prb_traverser init, first, last;
      int *cur, *prev, *next;

      prb_t_init (&init, tree);
      prb_t_first (&first, tree);
      prb_t_last (&last, tree);

      cur = prb_t_cur (&init);
      if (cur != NULL)
        {
          printf (" Inited traverser should be null, but is actually %d.\n",
                  *cur);
          okay = 0;
        }

      next = prb_t_next (&init);
      if (next != prb_t_cur (&first))
        {
          printf (" Next after null should be %d, but is actually %d.\n",
                  *(int *) prb_t_cur (&first), *next);
          okay = 0;
        }
      prb_t_prev (&init);

      prev = prb_t_prev (&init);
      if (prev != prb_t_cur (&last))
        {
          printf (" Previous before null should be %d, but is actually %d.\n",
                  *(int *) prb_t_cur (&last), *prev);
          okay = 0;
        }
      prb_t_next (&init);
    }

  return okay;
}
예제 #5
0
/* Examines the binary tree rooted at |node|.
   Zeroes |*okay| if an error occurs.
   Otherwise, does not modify |*okay|.
   Sets |*count| to the number of nodes in that tree,
   including |node| itself if |node != NULL|.
   Sets |*bh| to the tree's black-height.
   All the nodes in the tree are verified to be at least |min|
   but no greater than |max|. */
static void
recurse_verify_tree (struct prb_node *node, int *okay, size_t *count,
                     int min, int max, int *bh)
{
  int d;                /* Value of this node's data. */
  size_t subcount[2];   /* Number of nodes in subtrees. */
  int subbh[2];         /* Black-heights of subtrees. */
  int i;

  if (node == NULL)
    {
      *count = 0;
      *bh = 0;
      return;
    }
  d = *(int *) node->prb_data;

  if (min > max)
    {
      printf (" Parents of node %d constrain it to empty range %d...%d.\n",
              d, min, max);
      *okay = 0;
    }
  else if (d < min || d > max)
    {
      printf (" Node %d is not in range %d...%d implied by its parents.\n",
              d, min, max);
      *okay = 0;
    }

  recurse_verify_tree (node->prb_link[0], okay, &subcount[0],
                       min, d - 1, &subbh[0]);
  recurse_verify_tree (node->prb_link[1], okay, &subcount[1],
                       d + 1, max, &subbh[1]);
  *count = 1 + subcount[0] + subcount[1];
  *bh = (node->prb_color == PRB_BLACK) + subbh[0];

  if (node->prb_color != PRB_RED && node->prb_color != PRB_BLACK)
    {
      printf (" Node %d is neither red nor black (%d).\n",
              d, node->prb_color);
      *okay = 0;
    }

  /* Verify compliance with rule 1. */
  if (node->prb_color == PRB_RED)
    {
      if (node->prb_link[0] != NULL && node->prb_link[0]->prb_color == PRB_RED)
        {
          printf (" Red node %d has red left child %d\n",
                  d, *(int *) node->prb_link[0]->prb_data);
          *okay = 0;
        }

      if (node->prb_link[1] != NULL && node->prb_link[1]->prb_color == PRB_RED)
        {
          printf (" Red node %d has red right child %d\n",
                  d, *(int *) node->prb_link[1]->prb_data);
          *okay = 0;
        }
    }

  /* Verify compliance with rule 2. */
  if (subbh[0] != subbh[1])
    {
      printf (" Node %d has two different black-heights: left bh=%d, "
              "right bh=%d\n", d, subbh[0], subbh[1]);
      *okay = 0;
    }

  for (i = 0; i < 2; i++)
    {
      if (node->prb_link[i] != NULL
          && node->prb_link[i]->prb_parent != node)
        {
          printf (" Node %d has parent %d (should be %d).\n",
                  *(int *) node->prb_link[i]->prb_data,
                  (node->prb_link[i]->prb_parent != NULL
                   ? *(int *) node->prb_link[i]->prb_parent->prb_data : -1),
                  d);
          *okay = 0;
        }
    }
}
예제 #6
0
/* Examines the binary tree rooted at |node|.
   Zeroes |*okay| if an error occurs.
   Otherwise, does not modify |*okay|.
   Sets |*count| to the number of nodes in that tree,
   including |node| itself if |node != NULL|.
   Sets |*height| to the tree's height.
   All the nodes in the tree are verified to be at least |min|
   but no greater than |max|. */
static void
recurse_verify_tree (struct pavl_node *node, int *okay, size_t *count,
                     int min, int max, int *height)
{
  int d;                /* Value of this node's data. */
  size_t subcount[2];   /* Number of nodes in subtrees. */
  int subheight[2];     /* Heights of subtrees. */
  int i;

  if (node == NULL)
    {
      *count = 0;
      *height = 0;
      return;
    }
  d = *(int *) node->pavl_data;

  if (min > max)
    {
      printf (" Parents of node %d constrain it to empty range %d...%d.\n",
              d, min, max);
      *okay = 0;
    }
  else if (d < min || d > max)
    {
      printf (" Node %d is not in range %d...%d implied by its parents.\n",
              d, min, max);
      *okay = 0;
    }

  recurse_verify_tree (node->pavl_link[0], okay, &subcount[0],
                       min, d -  1, &subheight[0]);
  recurse_verify_tree (node->pavl_link[1], okay, &subcount[1],
                       d + 1, max, &subheight[1]);
  *count = 1 + subcount[0] + subcount[1];
  *height = 1 + (subheight[0] > subheight[1] ? subheight[0] : subheight[1]);

  if (subheight[1] - subheight[0] != node->pavl_balance)
    {
      printf (" Balance factor of node %d is %d, but should be %d.\n",
              d, node->pavl_balance, subheight[1] - subheight[0]);
      *okay = 0;
    }
  else if (node->pavl_balance < -1 || node->pavl_balance > +1)
    {
      printf (" Balance factor of node %d is %d.\n", d, node->pavl_balance);
      *okay = 0;
    }

  for (i = 0; i < 2; i++)
    {
      if (node->pavl_link[i] != NULL
          && node->pavl_link[i]->pavl_parent != node)
        {
          printf (" Node %d has parent %d (should be %d).\n",
                  *(int *) node->pavl_link[i]->pavl_data,
                  (node->pavl_link[i]->pavl_parent != NULL
                   ? *(int *) node->pavl_link[i]->pavl_parent->pavl_data : -1),
                  d);
          *okay = 0;
        }
    }
}