/* * Method: * void BTree::removeMin(void) * * Purpose: * Removes a pair associated witht the smallest key. * This is the very pair that findValForMinKey and * findMinKey pertain to. * * Input: * none * * Output: * none */ void BTree::removeMin(void) { Btree_Node* node=NULL; int idx; searchMin(&node,&idx); removeAtLeaf(node,idx); }
/* * Method: * unsigned long BTree::findValForMinKey(void) const * * Purpose: * Returns the value associated with a smallest key * in the BTree. * Throws an exception when tree is empty. * * Input: * none * * Output: * smallest key */ unsigned long BTree::findValForMinKey(void) const { Btree_Node* node=NULL; int idx; searchMin(&node,&idx); return (node->pair)[idx].val; }
PNode searchMin(PNode root){ if(root==NULL) return NULL; if(root->left!=NULL) return searchMin(root->left); else return root; }
//查找最小关键字,空树时返回NULL PNode searchMin(PNode root) { if(root == NULL) return NULL; if(root->left == NULL) return root; else //一直往左孩子找,直到没有左孩子的结点 return searchMin(root->left); }
void insertseq_sort( int * tab, int size ) { int x, p, i; for(i = 0; i < size; ++i ) { p = searchMin( tab, i, size ); x = tab[p]; shiftTab( tab, i, p ); tab[i] = x; } }
int main(void) { int i; PNode root=NULL; KeyType nodeArray[11]= {15,6,18,3,7,17,20,2,4,13,9}; create(&root,nodeArray,11); for(i=0; i<2; i++) deleteNode(&root,nodeArray[i]); printf("%d\n",searchPredecessor(root)->key); printf("%d\n",searchSuccessor(root)->key); printf("%d\n",searchMin(root)->key); printf("%d\n",searchMax(root)->key); printf("%d\n",search(root,13)->key); return 0; }
//查找某个结点的后继 PNode searchSuccessor(PNode p) { //空树 if(p==NULL) return p; //有右子树、右子树中最小的那个 if(p->right) return searchMin(p->right); //无右子树,查找某个结点的左子树遍历完了 else { if(p->parent == NULL) return NULL; //向上寻找后继 while(p) { if(p->parent->left == p) break; p=p->parent; } return p->parent; } }
Node* searchMin(Node* parent){ if (parent->lchild != NULL) //need to ensure if parent is NULL return searchMin(parent->lchild); else return parent; }
int main(int argc, char* argv[]) { const int NUM_OBJECTS = 40; // Number of objects in test set, must be > FRAC_OBJECTS for this test const int FRAC_OBJECTS = 4; const float MAX_WORLDSIZE = 10.0f; const float FRAC_WORLDSIZE = MAX_WORLDSIZE / 2; // typedef the RTree useage just for conveniance with iteration typedef RTree<SomeThing*, float, 3> SomeThingTree; ASSERT( NUM_OBJECTS > FRAC_OBJECTS ); int index; // general purpose counter, declared here because MSVC 6 is not ansi compliant with 'for' loops. SomeThing* thingArray[NUM_OBJECTS * 2]; // Store objects in another container to test with, sized larger than we need memset(thingArray, 0, sizeof(thingArray)); // Nullify array, size is known here // Create intance of RTree SomeThingTree tree; // Add some nodes int counter = 0; for( index = 0; index < NUM_OBJECTS; ++index ) { SomeThing* newThing = new SomeThing; newThing->m_creationCounter = counter++; newThing->m_min = Vec3(RandFloat(-MAX_WORLDSIZE, MAX_WORLDSIZE), RandFloat(-MAX_WORLDSIZE, MAX_WORLDSIZE), RandFloat(-MAX_WORLDSIZE, MAX_WORLDSIZE)); Vec3 extent = Vec3(RandFloat(0, FRAC_WORLDSIZE), RandFloat(0, FRAC_WORLDSIZE), RandFloat(0, FRAC_WORLDSIZE)); newThing->m_max = newThing->m_min + extent; thingArray[counter-1] = newThing; tree.Insert(newThing->m_min.v, newThing->m_max.v, newThing); printf("inserting %d\n", newThing->m_creationCounter); } printf("tree count = %d\n", tree.Count()); int numToDelete = NUM_OBJECTS / FRAC_OBJECTS; int numToStep = FRAC_OBJECTS; // Delete some nodes for( index = 0; index < NUM_OBJECTS; index += numToStep ) { SomeThing* curThing = thingArray[index]; if(curThing) { tree.Remove(curThing->m_min.v, curThing->m_max.v, curThing); printf("removing %d\n", curThing->m_creationCounter); delete curThing; thingArray[index] = NULL; } } printf("tree count = %d\n", tree.Count()); // Add some more nodes for( index = 0; index < numToDelete; ++index ) { SomeThing* newThing = new SomeThing; newThing->m_creationCounter = counter++; newThing->m_min = Vec3(RandFloat(-MAX_WORLDSIZE, MAX_WORLDSIZE), RandFloat(-MAX_WORLDSIZE, MAX_WORLDSIZE), RandFloat(-MAX_WORLDSIZE, MAX_WORLDSIZE)); Vec3 extent = Vec3(RandFloat(0, FRAC_WORLDSIZE), RandFloat(0, FRAC_WORLDSIZE), RandFloat(0, FRAC_WORLDSIZE)); newThing->m_max = newThing->m_min + extent; thingArray[counter-1] = newThing; tree.Insert(newThing->m_min.v, newThing->m_max.v, newThing); printf("inserting %d\n", newThing->m_creationCounter); } printf("tree count = %d\n", tree.Count()); Vec3 searchMin(0,0,0); Vec3 searchMax(FRAC_WORLDSIZE, FRAC_WORLDSIZE, FRAC_WORLDSIZE); tree.Search(searchMin.v, searchMax.v, &QueryResultCallback, NULL); // NOTE: Even better than just dumping text, it would be nice to render the // tree contents and search result for visualization. // List values. Iterator is NOT delete safe SomeThingTree::Iterator it; for( tree.GetFirst(it); !tree.IsNull(it); tree.GetNext(it) ) { SomeThing* curThing = tree.GetAt(it); if(BoxesIntersect(searchMin, searchMax, curThing->m_min, curThing->m_max)) { printf("brute found %d\n", curThing->m_creationCounter); } } // Delete our nodes, NOTE, we are NOT deleting the tree nodes, just our data // of course the tree will now contain invalid pointers that must not be used any more. for( tree.GetFirst(it); !tree.IsNull(it); tree.GetNext(it) ) { SomeThing* removeElem = tree.GetAt(it); if(removeElem) { printf("deleting %d\n", removeElem->m_creationCounter); delete removeElem; } } // Remove all contents (This would have happened automatically during destructor) tree.RemoveAll(); if(SomeThing::s_outstandingAllocs > 0) { printf("Memory leak!\n"); printf("s_outstandingAllocs = %d\n", SomeThing::s_outstandingAllocs); } else { printf("No memory leaks detected by app\n"); } // Wait for keypress on exit so we can read console output getchar(); #ifdef WIN32 // Use CRT Debug facility to dump memory leaks on app exit SET_CRT_DEBUG_FIELD( _CRTDBG_LEAK_CHECK_DF ); #endif //WIN32 return 0; }
void BinaryTree::del(std::shared_ptr<BinaryNode> node) { // If the node is a leaf if(node->left == nullptr && node->right == nullptr) { std::shared_ptr<BinaryNode> switchNode = node->parent; if(node != root) { if(node->parent->right == node) node->parent->right = nullptr; if(node->parent->left == node) node->parent->left = nullptr; } else { root = switchNode; } if(max == node) max = switchNode; if(min == node) min = switchNode; node->left = nullptr; node->right = nullptr; node->parent = nullptr; return; } // If the node only has a left child if(node->left != nullptr && node->right == nullptr) { node->left->parent = node->parent; if(node == root) { root = node->left; } else { if(node->parent->right == node) node->parent->right = node->left; if(node->parent->left == node) node->parent->left = node->left; } if(max == node) max = searchMax(node->left); node->left = nullptr; node->right = nullptr; node->parent = nullptr; return; } // If the node only has a right child if(node->left == nullptr && node->right != nullptr) { node->right->parent = node->parent; if(node == root) { root = node->right; root->parent = nullptr; } else { if(node->parent->right == node) node->parent->right = node->right; if(node->parent->left == node) node->parent->left = node->right; } if(min == node) min = searchMin(node->right); node->left = nullptr; node->right = nullptr; node->parent = nullptr; return; } // If the node has two children if(node->left != nullptr && node->right != nullptr) { std::shared_ptr<BinaryNode> rNode = searchMin(node->right); // Remove rNode from the tree if(rNode->right != nullptr){ rNode->right->parent = rNode->parent; rNode->parent->left = rNode->right; } // Replace node with rNode rNode->parent = node->parent; rNode->left = node->left; rNode->right = node->right; node->left->parent = rNode; node->right->parent = rNode; if(node == root){ root = rNode; } else { if(node->parent->right == node) node->parent->right = rNode; if(node->parent->left == node) node->parent->left = rNode; } node->left = nullptr; node->right = nullptr; node->parent = nullptr; return; } }