static int treeNodeTrim( treeNodeObj *node ) { int i; /* -------------------------------------------------------------------- */ /* Trim subtrees, and free subnodes that come back empty. */ /* -------------------------------------------------------------------- */ for(i=0; i<node->numsubnodes; i++ ) { if(treeNodeTrim(node->subnode[i])) { destroyTreeNode(node->subnode[i]); node->subnode[i] = node->subnode[node->numsubnodes-1]; node->numsubnodes--; i--; /* process the new occupant of this subnode entry */ } } if( node->numsubnodes == 1 && node->numshapes == 0 ) { node = node->subnode[0]; } /* if I only have 1 subnode promote that subnode to my positon */ /* -------------------------------------------------------------------- */ /* We should be trimmed if we have no subnodes, and no shapes. */ /* -------------------------------------------------------------------- */ return(node->numsubnodes == 0 && node->numshapes == 0); }
static void destroyTreeNode(treeNodeObj *node) { int i; for(i=0; i<node->numsubnodes; i++ ) { if(node->subnode[i]) destroyTreeNode(node->subnode[i]); } if(node->ids) free(node->ids); free(node); }
/* * Destroy a tree. */ void destroyTree(binTreeNode_t *pTree) { binTreeNode_t *pLeftChild = pTree->left, *pRightChild = pTree->right; if (pLeftChild != NULL) { destroyTree(pLeftChild); } if (pRightChild != NULL) { destroyTree(pRightChild); } destroyTreeNode(pTree); pTree = NULL; } /* end of destroyTree() */
static int treeNodeTrim( treeNodeObj *node ) { int i; /* -------------------------------------------------------------------- */ /* Trim subtrees, and free subnodes that come back empty. */ /* -------------------------------------------------------------------- */ for(i=0; i<node->numsubnodes; i++ ) { if(treeNodeTrim(node->subnode[i])) { destroyTreeNode(node->subnode[i]); node->subnode[i] = node->subnode[node->numsubnodes-1]; node->numsubnodes--; i--; /* process the new occupant of this subnode entry */ } } /* -------------------------------------------------------------------- */ /* If the current node has 1 subnode and no shapes, promote that */ /* subnode to the current node position. */ /* -------------------------------------------------------------------- */ if( node->numsubnodes == 1 && node->numshapes == 0) { treeNodeObj* psSubNode = node->subnode[0]; memcpy(&node->rect, &psSubNode->rect, sizeof(psSubNode->rect)); node->numshapes = psSubNode->numshapes; assert(node->ids == NULL); node->ids = psSubNode->ids; node->numsubnodes = psSubNode->numsubnodes; for( i = 0; i < psSubNode->numsubnodes; i++ ) node->subnode[i] = psSubNode->subnode[i]; free(psSubNode); } /* -------------------------------------------------------------------- */ /* We should be trimmed if we have no subnodes, and no shapes. */ /* -------------------------------------------------------------------- */ return(node->numsubnodes == 0 && node->numshapes == 0); }
void msDestroyTree(treeObj *tree) { destroyTreeNode(tree->root); free(tree); }
/* * Delete the first node found with key. */ void deleteTreeNode(binTreeNode_t **ppTree, binTreeNode_t *pDelNode, binTreeNode_t *pDelParent, int bLeftChild) { binTreeNode_t *leftChild, *rightChild; binTreeNode_t *pSmallest = NULL, *pSmallestParent = NULL; int bSmallestLeftChild = 0; if (pDelNode != NULL) { /* remove node then update subtrees */ leftChild = pDelNode->left; rightChild = pDelNode->right; /* update */ /* no children */ if (leftChild == NULL && rightChild == NULL) { /* root node to be deleted */ if (pDelNode == *ppTree) { destroyTreeNode(pDelNode); *ppTree = NULL; } /* not root node, so can just deallocate memory */ else { destroyTreeNode(pDelNode); if (bLeftChild) { pDelParent->left = NULL; } else { pDelParent->right = NULL; } } } /* two children */ else if (leftChild != NULL && rightChild != NULL) { pSmallest = findSmallest(rightChild, &pSmallestParent, &bSmallestLeftChild); /* exchange pSmallest with deleted node */ swapNodes(ppTree, pDelNode, &pDelParent, &bLeftChild, pSmallest, &pSmallestParent, &bSmallestLeftChild); /* delete the pDelNode now */ deleteTreeNode(ppTree, pDelNode, pDelParent, bLeftChild); } /* one child */ else if (leftChild != NULL) { assert(rightChild == NULL); /* root node to be deleted */ if (pDelNode == *ppTree) { destroyTreeNode(pDelNode); pDelNode = NULL; *ppTree = leftChild; } /* not root node */ else { destroyTreeNode(pDelNode); if (bLeftChild) { pDelParent->left = leftChild; } else { pDelParent->right = leftChild; } } } else if (rightChild != NULL) { assert(leftChild == NULL); /* root node to be deleted */ if (pDelNode == *ppTree) { destroyTreeNode(pDelNode); pDelNode = NULL; *ppTree = rightChild; } /* not root node */ else { destroyTreeNode(pDelNode); if (bLeftChild) { pDelParent->left = rightChild; } else { pDelParent->right = rightChild; } } } } } /* end of deleteNode() */