BstNode<KEY, VALUE>* AvlTree<KEY, VALUE>::InsertNode (const KEY& insertkey, VALUE* insertvalue, int StoreAttrib_, BstNode<KEY, VALUE>* tree, int& confirm) { if (tree == NULL) { confirm = 1; return MakeNode(insertkey, insertvalue, StoreAttrib_); } if (insertkey < tree->key) tree->left = InsertNode(insertkey, insertvalue, StoreAttrib_, tree->left, confirm); else if (insertkey > tree->key) tree->right = InsertNode(insertkey, insertvalue, StoreAttrib_, tree->right, confirm); else { confirm = 0; StoreAttrib_ |= DataStorageAttributes::ACTIVE; tree->value.AssignPtr(insertvalue, StoreAttrib_); if (tree->value.Pointee() == NULL) cerr <<ERRMSG_NOMEMBST; } if (confirm) return Rebalance(tree); return tree; }
BstNode<KEY, VALUE>* AvlTree<KEY, VALUE>::InsertNode (const KEY& insertkey, const DataStorePtr<VALUE>& insertvalue, BstNode<KEY, VALUE>* tree, int& confirm) { if (tree == NULL) { confirm = 1; return MakeNode(insertkey, insertvalue); } if (insertkey < tree->key) tree->left = InsertNode(insertkey, insertvalue, tree->left, confirm); else if (insertkey > tree->key) tree->right = InsertNode(insertkey, insertvalue, tree->right, confirm); else { confirm = 0; tree->value = insertvalue; if (tree->value.Pointee() == NULL) cerr <<ERRMSG_NOMEMBST; } if (confirm) return Rebalance(tree); return tree; }
// Create a proxy in the tree as a leaf node. We return the index // of the node instead of a pointer so that we can grow // the node pool. int32 b2DynamicTree::CreateProxy(const b2AABB& aabb, void* userData) { int32 proxyId = AllocateNode(); // Fatten the aabb. b2Vec2 r(b2_aabbExtension, b2_aabbExtension); m_nodes[proxyId].aabb.lowerBound = aabb.lowerBound - r; m_nodes[proxyId].aabb.upperBound = aabb.upperBound + r; m_nodes[proxyId].userData = userData; InsertLeaf(proxyId); // Rebalance if necessary. int32 iterationCount = m_nodeCount >> 4; int32 tryCount = 0; int32 height = ComputeHeight(); while (height > 64 && tryCount < 10) { Rebalance(iterationCount); height = ComputeHeight(); ++tryCount; } return proxyId; }
BstNode<KEY, VALUE>* AvlTree<KEY, VALUE>::RmRight(BstNode<KEY, VALUE>* tree) { BstNode<KEY, VALUE>* tnode = tree; tree = tnode->right; tree->left = tnode->left; return Rebalance(tree); }
BstNode<KEY, VALUE>* AvlTree<KEY, VALUE>::DelNode(const KEY& deletekey, BstNode<KEY, VALUE>* tree) { BstNode<KEY, VALUE>* retp; // returned pointer to delete. if (tree == NULL) // Quit if searching empty tree. return NULL; if (tree -> key > deletekey) // See if node to delete is in one { // one of the subtrees. tree->left = DelNode(deletekey, tree->left); return Rebalance(tree); } else if (tree -> key < deletekey) { tree->right = DelNode(deletekey, tree->right); return Rebalance(tree); } if (tree->right && tree->left) { retp = tree; tree = RmHasBoth(tree); } else if (tree->left) { retp = tree; tree = retp->left; } else if (tree->right) { retp = tree; tree = retp->right; } else { retp = tree; tree = NULL; } if (retp) delete retp; return tree; }
BstNode<KEY, VALUE>* AvlTree<KEY, VALUE>::RmRightSubl(BstNode<KEY, VALUE>* tree, BstNode<KEY, VALUE>* piv) { BstNode<KEY, VALUE>* newpiv; if (tree->left->left) { newpiv = RmRightSubl(tree->left, piv); tree->left = Rebalance(tree->left); return newpiv; } newpiv = tree->left; tree->left = newpiv->right; newpiv->left = piv->left; newpiv->right = piv->right; newpiv->right = Rebalance(newpiv->right); return Rebalance(newpiv); }
BTreeNode* BSTInsert(BTreeNode **pRoot,BSTData data){ //BTreeNode *pNode=NULL; //BTreeNode *cNode=*pRoot; //BTreeNode *nNode=NULL; ////위치 찾기 //while(cNode!=NULL){ // if(data==GetData(cNode)) return; // pNode=cNode; // if(GetData(cNode)<data) cNode=GetRightSubTree(cNode); // else cNode=GetLeftSubTree(cNode); //} // //nNode=MakeBTreeNode(); //SetData(nNode,data); //if(pNode!=NULL){ //삽입 노드가 루트노드가 아닌 경우 // if(GetData(pNode)<data) MakeRightSubTree(pNode,nNode); // else MakeLeftSubTree(pNode,nNode); //} //else //삽입 되는 노드가 루트 노드가 되는 경우 // *pRoot=nNode; if(*pRoot==NULL){ *pRoot=MakeBTreeNode(); SetData(*pRoot,data); } else if(GetData(*pRoot)>data){ BSTInsert(&((*pRoot)->left),data); *pRoot=Rebalance(pRoot); } else if(GetData(*pRoot)<data){ BSTInsert(&((*pRoot)->right),data); *pRoot=Rebalance(pRoot); } else return NULL; //키(data) 중복 return *pRoot; }
BTreeNode* BSTRemove(BTreeNode** pRoot,BSTData target){ BTreeNode *pVRoot=MakeBTreeNode(); BTreeNode *pNode=pVRoot; BTreeNode *cNode=*pRoot; BTreeNode *dNode,*dcNode,*mNode,*mpNode; BSTData delData; //가상 노드의 오른쪽 자식이 루트노드 ChangeRightSubTree(pVRoot,*pRoot); //삭제 대상 검색 while(cNode!=NULL && GetData(cNode)!=target){ pNode=cNode; if(target<GetData(cNode)) cNode=GetLeftSubTree(cNode); else cNode=GetRightSubTree(cNode); } if(cNode==NULL) return NULL; dNode=cNode; //단말 노드인 경우 if(GetLeftSubTree(dNode)==NULL && GetRightSubTree(dNode)==NULL){ if(GetLeftSubTree(pNode)==dNode) RemoveLeftSubTree(pNode); else RemoveRightSubTree(pNode); } //하나의 자식 노드를 갖는 경우 else if(GetLeftSubTree(dNode)==NULL || GetRightSubTree(dNode)==NULL){ if(GetLeftSubTree(dNode)!=NULL) dcNode=GetLeftSubTree(dNode); else dcNode=GetRightSubTree(dNode); if(GetLeftSubTree(pNode)==dNode) ChangeLeftSubTree(pNode,dcNode); else ChangeRightSubTree(pNode,dcNode); } //두 개의 자식 노드를 갖는 경우 else{ //삭제 노드를 대체할 노드는 삭제 노드의 오른쪽 서브트리에서의 가장 작은 값을 가진 노드 mNode=GetRightSubTree(dNode); //대체노드 mpNode=dNode;//대체노드의 부모노드 //삭제 대상의 대체 노드를 찾음 while(GetLeftSubTree(mNode)!=NULL){ mpNode=mNode; mNode=GetLeftSubTree(mNode); } //대체노드에 저장된 값을 삭제할 노드에 저장 delData=GetData(dNode); //삭제 될 노드 값 백업 SetData(dNode,GetData(mNode)); //대체노드의 부모노드와 자식노드를 연결 if(GetLeftSubTree(mpNode)==mNode) ChangeLeftSubTree(mpNode,GetRightSubTree(mNode)); else ChangeRightSubTree(mpNode,GetRightSubTree(mNode)); dNode=mNode; SetData(dNode,delData); } //삭제된 노드가 루트노드인 경우 if(GetRightSubTree(pVRoot)!=*pRoot) *pRoot=GetRightSubTree(pVRoot); free(pVRoot); *pRoot=Rebalance(pRoot); return dNode; }