/* 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]; }
/* 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; } }
/* 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; } } }
/* 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; }
/* 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; } } }
/* 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; } } }