//=========================================== // Polygon::Polygon //=========================================== Polygon::Polygon(const XmlNode data) : Asset(internString("Polygon")), m_outlineModel(Renderer::LINES), m_interiorModel(Renderer::TRIANGLES), m_renderer(Renderer::getInstance()) { try { XML_NODE_CHECK(data, Polygon); clear(); XmlNode node = data.firstChild(); while (!node.isNull() && node.name() == "Vec2f") { boost::shared_ptr<Vec2f> vert(new Vec2f(node)); m_verts.push_back(vert); ++m_nVerts; node = node.nextSibling(); } } catch (XmlException& e) { e.prepend("Error parsing XML for instance of class Polygon; "); throw; } restructure(); updateModels(); }
PHierarchicalCluster THierarchicalClustering::operator()(PSymMatrix distanceMatrix) { float *distanceMatrixElements = NULL; TClusterW **clusters, *root; float *callbackMilestones = NULL; try { const int dim = distanceMatrix->dim; const int size = ((dim+1)*(dim+2))/2; float *distanceMatrixElements = overwriteMatrix ? distanceMatrix->elements : (float *)memcpy(new float[size], distanceMatrix->elements, size*sizeof(float)); clusters = init(dim, distanceMatrixElements); callbackMilestones = (progressCallback && (distanceMatrix->dim >= 1000)) ? progressCallback->milestones(distanceMatrix->dim) : NULL; root = merge(clusters, callbackMilestones); } catch (...) { mldelete clusters; mldelete callbackMilestones; mldelete distanceMatrixElements; throw; } mldelete clusters; mldelete callbackMilestones; mldelete distanceMatrixElements; return restructure(root); }
PHierarchicalCluster THierarchicalClustering::restructure(TClusterW *root) { PIntList elementIndices = new TIntList(root->size); TIntList::iterator currentElement(elementIndices->begin()); int currentIndex = 0; return restructure(root, elementIndices, currentElement, currentIndex); }
PHierarchicalCluster THierarchicalClustering::restructure(TClusterW *node, PIntList elementIndices, TIntList::iterator ¤tElement, int ¤tIndex) { PHierarchicalCluster cluster; if (!node->left) { *currentElement++ = node->elementIndex; cluster = mlnew THierarchicalCluster(elementIndices, currentIndex++); } else { PHierarchicalCluster left = restructure(node->left, elementIndices, currentElement, currentIndex); PHierarchicalCluster right = restructure(node->right, elementIndices, currentElement, currentIndex); cluster = mlnew THierarchicalCluster(elementIndices, left, right, node->height, left->first, right->last); } // no need to care about 'distances' - they've been removed during clustering (in 'elevate') :) mldelete node; return cluster; }
//=========================================== // Polygon::removeVertex //=========================================== void Polygon::removeVertex(int idx) { if (idx > m_nVerts - 1 || idx < 0) throw Exception("Index out of range", __FILE__, __LINE__); for (int i = idx; i < m_nVerts - 1; ++i) m_verts[i] = m_verts[i + 1]; --m_nVerts; restructure(); updateModels(); }
//=========================================== // Polygon::addVertex //=========================================== void Polygon::addVertex(const Vec2f& vert) { if (m_nVerts >= MAX_VERTS) { stringstream msg; msg << "Error adding vertex; MAX_VERTS = " << MAX_VERTS; throw Exception(msg.str(), __FILE__, __LINE__); } m_verts.push_back(boost::shared_ptr<Vec2f>(new Vec2f(vert))); ++m_nVerts; restructure(); updateModels(); }
//=========================================== // Polygon::insertVertex //=========================================== void Polygon::insertVertex(int idx, const Vec2f& vert) { if (idx > m_nVerts - 1 || idx < 0) throw Exception("Index out of range", __FILE__, __LINE__); ++m_nVerts; for (int i = m_nVerts - 1; i > idx; --i) m_verts[i] = m_verts[i - 1]; *m_verts[idx] = vert; restructure(); updateModels(); }
//=========================================== // Polygon::deepCopy //=========================================== void Polygon::deepCopy(const Polygon& copy) { m_verts.clear(); m_nVerts = 0; for (int i = 0; i < copy.m_nVerts; ++i) { boost::shared_ptr<Vec2f> vert(new Vec2f(*copy.m_verts[i])); // Make copy of vertex m_verts.push_back(vert); } m_nVerts = copy.m_nVerts; restructure(); m_outlineModel = copy.m_outlineModel; m_interiorModel = copy.m_interiorModel; }
static void rbmTreeInsertionCleanup(struct rbmTree *t, struct rbTreeNode *p, struct rbTreeNode *x, int tos) /* Restructuring or recolouring will be needed if node x and its parent, p, * are both red. */ { struct rbTreeNode **stack = t->stack; struct rbTreeNode *q, *m; while(p->color == rbTreeRed) { /* Double red problem. */ /* Obtain a pointer to p's parent, m, and sibling, q. */ m = stack[--tos]; q = p == m->left ? m->right : m->left; /* Determine whether restructuring or recolouring is needed. */ if(!q || q->color == rbTreeBlack) { /* Sibling is black. ==> Perform restructuring. */ /* Restructure according to the left to right order, of nodes * m, p, and x. */ m = restructure(t, tos, m, p, x); m->color = rbTreeBlack; m->left->color = m->right->color = rbTreeRed; /* Restructuring eliminates the double red problem. */ break; } /* else just need to flip color */ /* Sibling is also red. ==> Perform recolouring. */ p->color = rbTreeBlack; q->color = rbTreeBlack; if(tos == 0) break; /* The root node always remains black. */ m->color = rbTreeRed; /* Continue, checking colouring higher up. */ x = m; p = stack[--tos]; } }
int hash_insert ( void *el, hashtab *htab) { int i; hashnode *hnode; ++htab->cardinal; if (htab->cardinal > htab->size * 10) { restructure (htab); } hnode = new hashnode[sizeof (*hnode)]; if (hnode == NULL) return 1; i = HASH (htab, el); hnode->next = htab->vec[i]; hnode->el = el; htab->vec[i] = hnode; return 0; }
void *rbTreeRemove(struct rbTree *t, void *item) /* rbTreeRemove() - Delete an item in the red-black tree with the same key as * the item pointed to by `item'. Returns a pointer to the deleted item, * and NULL if no item was found. */ { struct rbTreeNode *p, *r, *x, *y, *z, *b, *newY; struct rbTreeNode *m; rbTreeColor removeCol; void *returnItem; int (* compare)(void *, void *); int cmpResult; struct rbTreeNode **stack; int i, tos; /* Attempt to locate the item to be deleted. */ if((p = t->root)) { compare = t->compare; stack = t->stack; tos = 0; for(;;) { stack[tos++] = p; cmpResult = compare(item, p->item); if(cmpResult < 0) p = p->left; else if(cmpResult > 0) p = p->right; else /* Item found. */ break; if(!p) return NULL; } } else return NULL; /* p points to the node to be deleted, and is currently on the top of the * stack. */ if(!p->left) { tos--; /* Adjust tos to remove p. */ /* Right child replaces p. */ if(tos == 0) { r = t->root = p->right; x = y = NULL; } else { x = stack[--tos]; if(p == x->left) { r = x->left = p->right; y = x->right; } else { r = x->right = p->right; y = x->left; } } removeCol = p->color; } else if(!p->right) { tos--; /* Adjust tos to remove p. */ /* Left child replaces p. */ if(tos == 0) { r = t->root = p->left; x = y = NULL; } else { x = stack[--tos]; if(p == x->left) { r = x->left = p->left; y = x->right; } else { r = x->right = p->left; y = x->left; } } removeCol = p->color; } else { /* Save p's stack position. */ i = tos-1; /* Minimum child, m, in the right subtree replaces p. */ m = p->right; do { stack[tos++] = m; m = m->left; } while(m); m = stack[--tos]; /* Update either the left or right child pointers of p's parent. */ if(i == 0) { t->root = m; } else { x = stack[i-1]; /* p's parent. */ if(p == x->left) { x->left = m; } else { x->right = m; } } /* Update the tree part m is removed from, and assign m the child * pointers of p (only if m is not the right child of p). */ stack[i] = m; /* Node m replaces node p on the stack. */ x = stack[--tos]; r = m->right; if(tos != i) { /* x is equal to the parent of m. */ y = x->right; x->left = r; m->right = p->right; } else { /* m was the right child of p, and x is equal to m. */ y = p->left; } m->left = p->left; /* We treat node m as the node which has been removed. */ removeCol = m->color; m->color = p->color; } /* Get return value and reuse the space used by node p. */ returnItem = p->item; p->right = t->freeList; t->freeList = p; t->n--; /* The pointers x, y, and r point to nodes which may be involved in * restructuring and recolouring. * x - the parent of the removed node. * y - the sibling of the removed node. * r - the node which replaced the removed node. * From the above code, the next entry off the stack will be the parent of * node x. */ /* The number of black nodes on paths to all external nodes (NULL child * pointers) must remain the same for all paths. Restructuring or * recolouring of nodes may be necessary to enforce this. */ if(removeCol == rbTreeBlack) { /* Removal of a black node requires some adjustment. */ if(!r || r->color == rbTreeBlack) { /* A black node replaced the deleted black node. Note that * external nodes (NULL child pointers) are always black, so * if r is NULL it is treated as a black node. */ /* This causes a double-black problem, since node r would need to * be coloured double-black in order for the black color on * paths through r to remain the same as for other paths. */ /* If r is the root node, the double-black color is not necessary * to maintain the color balance. Otherwise, some adjustment of * nearby nodes is needed in order to eliminate the double-black * problem. NOTE: x points to the parent of r. */ if(x) for(;;) { /* There are three adjustment cases: * 1. r's sibling, y, is black and has a red child, z. * 2. r's sibling, y, is black and has two black children. * 3. r's sibling, y, is red. */ if(y->color == rbTreeBlack) { /* Note the conditional evaluation for assigning z. */ if(((z = y->left) && z->color == rbTreeRed) || ((z = y->right) && z->color == rbTreeRed)) { /* Case 1: perform a restructuring of nodes x, y, and * z. */ b = restructure(t, tos, x, y, z); b->color = x->color; b->left->color = b->right->color = rbTreeBlack; break; } else { /* Case 2: recolour node y red. */ y->color = rbTreeRed; if(x->color == rbTreeRed) { x->color = rbTreeBlack; break; } /* else */ if(tos == 0) break; /* Root level reached. */ /* else */ r = x; x = stack[--tos]; /* x <- parent of x. */ y = x->left == r ? x->right : x->left; } } else { /* Case 3: Restructure nodes x, y, and z, where: * - If node y is the left child of x, then z is the left * child of y. Otherwise z is the right child of y. */ if(x->left == y) { newY = y->right; z = y->left; } else { newY = y->left; z = y->right; } restructure(t, tos, x, y, z); y->color = rbTreeBlack; x->color = rbTreeRed; /* Since x has moved down a place in the tree, and y is the * new the parent of x, the stack must be adjusted so that * the parent of x is correctly identified in the next call * to restructure(). */ stack[tos++] = y; /* After restructuring, node r has a black sibling, newY, * so either case 1 or case 2 applies. If case 2 applies * the double-black problem does not reappear. */ y = newY; /* Note the conditional evaluation for assigning z. */ if(((z = y->left) && z->color == rbTreeRed) || ((z = y->right) && z->color == rbTreeRed)) { /* Case 1: perform a restructuring of nodes x, y, and * z. */ b = restructure(t, tos, x, y, z); b->color = rbTreeRed; /* Since node x was red. */ b->left->color = b->right->color = rbTreeBlack; } else { /* Case 2: recolour node y red. */ /* Note that node y is black and node x is red. */ y->color = rbTreeRed; x->color = rbTreeBlack; } break; } } } else { /* A red node replaced the deleted black node. */ /* In this case we can simply color the red node black. */ r->color = rbTreeBlack; } } return returnItem; }
void *rbTreeAdd(struct rbTree *t, void *item) /* rbTreeAdd() - Inserts an item into the red-black tree pointed to by t, * according the the value its key. The key of an item in the red-black * tree must be unique among items in the tree. If an item with the same key * already exists in the tree, a pointer to that item is returned. Otherwise, * NULL is returned, indicating insertion was successful. */ { struct rbTreeNode *x, *p, *q, *m, **attachX; int (* compare)(void *, void *); int cmpResult; rbTreeColor col; struct rbTreeNode **stack = NULL; int tos; tos = 0; if((p = t->root) != NULL) { compare = t->compare; stack = t->stack; /* Repeatedly explore either the left branch or the right branch * depending on the value of the key, until an empty branch is chosen. */ for(;;) { stack[tos++] = p; cmpResult = compare(item, p->item); if(cmpResult < 0) { p = p->left; if(!p) { p = stack[--tos]; attachX = &p->left; break; } } else if(cmpResult > 0) { p = p->right; if(!p) { p = stack[--tos]; attachX = &p->right; break; } } else { return p->item; } } col = rbTreeRed; } else { attachX = &t->root; col = rbTreeBlack; } /* Allocate new node and place it in tree. */ if ((x = t->freeList) != NULL) t->freeList = x->right; else lmAllocVar(t->lm, x); x->left = x->right = NULL; x->item = item; x->color = col; *attachX = x; t->n++; /* Restructuring or recolouring will be needed if node x and its parent, p, * are both red. */ if(tos > 0) { while(p->color == rbTreeRed) { /* Double red problem. */ /* Obtain a pointer to p's parent, m, and sibling, q. */ m = stack[--tos]; q = p == m->left ? m->right : m->left; /* Determine whether restructuring or recolouring is needed. */ if(!q || q->color == rbTreeBlack) { /* Sibling is black. ==> Perform restructuring. */ /* Restructure according to the left to right order, of nodes * m, p, and x. */ m = restructure(t, tos, m, p, x); m->color = rbTreeBlack; m->left->color = m->right->color = rbTreeRed; /* Restructuring eliminates the double red problem. */ break; } /* else just need to flip color */ /* Sibling is also red. ==> Perform recolouring. */ p->color = rbTreeBlack; q->color = rbTreeBlack; if(tos == 0) break; /* The root node always remains black. */ m->color = rbTreeRed; /* Continue, checking colouring higher up. */ x = m; p = stack[--tos]; } } return NULL; }
// Add a record to the dictionary. Returns false if key already exists bool AVLDictionary::addRecord( KeyType key, DataType record) { //printf("start\n"); URLNumList *temp = new URLNumList(); DictMember *current = root; DictMember *previous = NULL; while(current !=NULL){ //printf("while,key = %s, current word = %s\n",key,current->word); if(strcmp(key,current->word) == 0){ // word exist add to the URLNUMList //essentially follows array-dict's way with array[i] replaced by current temp = (URLNumList*)record; if (temp -> _num <= current->list -> _num){ //insert before lesser value temp -> _next = current->list; current->list = temp; } else{ URLNumList *iterator = current->list; while(iterator->_next != NULL && iterator->_next->_num < temp -> _num){ //insert after higher value iterator = iterator->_next; } temp->_next = iterator->_next; iterator->_next = temp; } return true; //no restructuring needed }//end if(strcmp(key,current->word) == 0) else if( strcmp(key,current->word) < 0 ){ //printf("left"); //printf("%d, %d",strcmp("near","nancy"),strcmp(key,current->word)); previous = current; current = current ->left; } else if( strcmp(key,current->word) > 0){ //just change to else for optimization //printf("right"); previous = current; current = current ->right; } } // end while(current !=NULL){ //need to create new node //printf("newnode\n"); DictMember * n = new DictMember(); n->height = 1; n->word = strdup(key); n->list = (URLNumList*)record; n->left = NULL; n->right = NULL; n->parent = previous; if(previous == NULL){ //tree is empty, insert at root root = n; //printf("insert root\n"); } else{ if(strcmp(key,previous->word)<0){ previous->left = n; } else{ previous->right = n; } } //Adjust the height of the tree DictMember * m = n->parent; while(m != NULL){ //get maximum height of the left and right child int maxheight = 0; if(m->left!=NULL){ maxheight = m->left->height; } if(m->right != NULL && maxheight < m->right->height){ maxheight = m->right->height; } m->height = 1+maxheight; m=m->parent; } //Restructure restructure(n); return false; }
// Removes one element from the dictionary bool AVLDictionary::removeElement(KeyType key) { if (debug) { printf("------------------------------------\n"); printf("removeElement(\"%s\")\n", key); printf("---------- Before -----------------\n"); printNode("", root, 0); } AVLNode *node; node = findNode(key); if (node == NULL) { return false; } if (node->left == NULL && node->right == NULL) { if ( node == node->parent->left) { node->parent->left = NULL; } else { node->parent->right = NULL; } AVLNode *m; m = node->parent; while(m != NULL) { int maxheight = 0; if(m->left != NULL) { maxheight = m->left->height; } if (m->right != NULL && maxheight < m->right->height) { maxheight = m->right->height; } m->height = maxheight +1; m = m->parent; } restructure(node->parent); delete node; } else if (node->left == NULL) { AVLNode temp; temp.height = node->height; strcpy((char*)temp.key, node->key); temp.data = node->data; node->height = node->right->height; strcpy((char*)node->key, node->right->key); node->data = node->right->data; node->right->height = temp.height; strcpy((char*)node->right->key, temp.key); node->right->data = temp.data; delete node->right; node->right = NULL; AVLNode *m = node->parent; while(m != NULL) { int maxheight = 0; if(m->left != NULL) { maxheight = m->left->height; } if (m->right != NULL && maxheight < m->right->height) { maxheight = m->right->height; } m->height = maxheight +1; m = m->parent; } restructure(node); } else if (node->right == NULL) { AVLNode temp; temp.height = node->height; strcpy((char*)temp.key, node->key); temp.data = node->data; node->height = node->left->height; strcpy((char*)node->key, node->left->key); node->data = node->left->data; node->left->height = temp.height; strcpy((char*)node->left->key, temp.key); node->left->data = temp.data; delete node->left; node->left = NULL; AVLNode *m; m = node->parent; while(m != NULL) { int maxheight = 0; if( m->left != NULL) { maxheight = m->left->height; } if (m->right != NULL && maxheight < m->right->height) { maxheight = m->right->height; } m->height = maxheight +1; m = m->parent; } restructure(node); } else { AVLNode *replacement; replacement = node->left; if (replacement->right == NULL) { replacement = node->right; while(replacement->left != NULL) { replacement = replacement->left; } } else { while (replacement->right != NULL) { replacement = replacement->right; } } AVLNode temp; temp.height = node->height; strcpy((char*)temp.key, node->key); temp.data = node->data; node->height = replacement->height; strcpy((char*)node->key, replacement->key); node->data = replacement->data; replacement->height = temp.height; strcpy((char*)replacement->key, temp.key); replacement->data = temp.data; AVLNode *n; n = replacement->parent; if (n != NULL) { if (replacement == n->left) { n->left = NULL; delete replacement; } else { n->right = NULL; delete replacement; } AVLNode *m = n; while(m != NULL) { int maxheight = 0; if(m->left != NULL) { maxheight = m->left->height; } if (m->right != NULL && maxheight < m->right->height) { maxheight = m->right->height; } m->height = maxheight +1; m = m->parent; } restructure(n); } } nElements--; if (debug) { printf("---------- After -----------------\n"); printNode("", root, 0); checkRecursive(root); } return true; }
// Add a record to the dictionary. Returns false if key already exists bool AVLDictionary::addRecord( KeyType key, DataType record) { if (debug) { printf("------------------------------------\n"); printf("addRecord(\"%s\",%d)\n", key, record); printf("---------- Before -----------------\n"); printNode("", root, 0); } AVLNode *n; n = new AVLNode(); n->key = key; n->data = record; n->height = 1; n->left = NULL; n->right = NULL; n->parent = NULL; if(root == NULL) { root = n; nElements++; return true; } AVLNode *curr; curr = root; AVLNode *prev; prev = NULL; while(curr != NULL) { prev = curr; if (strcmp(key, curr->key) < 0) { curr = curr->left; } else if (strcmp(key, curr->key) > 0) { curr = curr->right; } else { curr->data = record; return false; } } if (strcmp(key, prev->key) < 0) { prev->left = n; } else { prev->right = n; } n->parent = prev; AVLNode *m; m = n->parent; while(m != NULL) { int maxheight = 0; if(m->left != NULL) maxheight = m->left->height; if(m->right != NULL && maxheight < m->right->height) maxheight = m->right->height; m->height = 1+maxheight; m = m->parent; } if (debug) { printf("---------- Before Restructure -----------------\n"); printNode("", root, 0); } restructure(n); if (debug) { checkRecursive(root); printf("---------- After Restructure -----------------\n"); printNode("", root, 0); } nElements++; return true; }
static void rbmTreeDeletionCleanup(struct rbmTree *t, struct rbTreeNode *x, struct rbTreeNode *y, struct rbTreeNode *r, int tos) /* Removal of a black node requires some adjustment. */ /* The pointers x, y, and r point to nodes which may be involved in * restructuring and recolouring. * x - the parent of the removed node. * y - the sibling of the removed node. * r - the node which replaced the removed node. * The next entry off the stack will be the parent of node x. */ { struct rbTreeNode **stack = t->stack; struct rbTreeNode *z, *b, *newY; if(!r || r->color == rbTreeBlack) { /* A black node replaced the deleted black node. Note that * external nodes (NULL child pointers) are always black, so * if r is NULL it is treated as a black node. */ /* This causes a double-black problem, since node r would need to * be coloured double-black in order for the black color on * paths through r to remain the same as for other paths. */ /* If r is the root node, the double-black color is not necessary * to maintain the color balance. Otherwise, some adjustment of * nearby nodes is needed in order to eliminate the double-black * problem. NOTE: x points to the parent of r. */ if(x) for(;;) { /* There are three adjustment cases: * 1. r's sibling, y, is black and has a red child, z. * 2. r's sibling, y, is black and has two black children. * 3. r's sibling, y, is red. */ if(y->color == rbTreeBlack) { /* Note the conditional evaluation for assigning z. */ if(((z = y->left) && z->color == rbTreeRed) || ((z = y->right) && z->color == rbTreeRed)) { /* Case 1: perform a restructuring of nodes x, y, and * z. */ b = restructure(t, tos, x, y, z); b->color = x->color; b->left->color = b->right->color = rbTreeBlack; break; } else { /* Case 2: recolour node y red. */ y->color = rbTreeRed; if(x->color == rbTreeRed) { x->color = rbTreeBlack; break; } /* else */ if(tos == 0) break; /* Root level reached. */ /* else */ r = x; x = stack[--tos]; /* x <- parent of x. */ y = x->left == r ? x->right : x->left; } } else { /* Case 3: Restructure nodes x, y, and z, where: * - If node y is the left child of x, then z is the left * child of y. Otherwise z is the right child of y. */ if(x->left == y) { newY = y->right; z = y->left; } else { newY = y->left; z = y->right; } restructure(t, tos, x, y, z); y->color = rbTreeBlack; x->color = rbTreeRed; /* Since x has moved down a place in the tree, and y is the * new the parent of x, the stack must be adjusted so that * the parent of x is correctly identified in the next call * to restructure(). */ stack[tos++] = y; /* After restructuring, node r has a black sibling, newY, * so either case 1 or case 2 applies. If case 2 applies * the double-black problem does not reappear. */ y = newY; /* Note the conditional evaluation for assigning z. */ if(((z = y->left) && z->color == rbTreeRed) || ((z = y->right) && z->color == rbTreeRed)) { /* Case 1: perform a restructuring of nodes x, y, and * z. */ b = restructure(t, tos, x, y, z); b->color = rbTreeRed; /* Since node x was red. */ b->left->color = b->right->color = rbTreeBlack; } else { /* Case 2: recolour node y red. */ /* Note that node y is black and node x is red. */ y->color = rbTreeRed; x->color = rbTreeBlack; } break; } } } else { /* A red node replaced the deleted black node. */ /* In this case we can simply color the red node black. */ r->color = rbTreeBlack; } }
// Add a record to the dictionary. Returns false if key already exists bool AVLDictionary::addRecord( KeyType key, DataType data) { if ( debug) { printf("------------------------------------\n"); printf("addRecord(\"%s\",%d)\n", key, (int)data); printf("---------- Before -----------------\n"); printNode("", root, 0); } //find node with that key, if any //overwrite data if found AVLNode *current = root; AVLNode *prev = NULL; while (current != NULL) { prev = current; if (strcmp(key, current->key) == 0) { // key == current->key) // //found, overwrite data current->data = data; return false; } else if (strcmp(key, current->key) > 0) { // (key - current->key > 0) //key is in right subtree current = current->right; } else { //key is in left subtree current = current->left; } } //did not find key in tree, and prev points to parent node where new node will be inserted AVLNode *newNode = new AVLNode(); newNode->key = strdup(key); //use strdup if key is const char* newNode->data = data; newNode->height = 1; newNode->left = NULL; newNode->right = NULL; newNode->parent = prev; if (prev == NULL) { //tree is empty, assign to root root = newNode; nElements++; return true; } if (strcmp(key, prev->key) > 0) { //attach to right prev->right = newNode; } else { prev->left = newNode; } //adjust heights of above subtrees, path from inserted node to root AVLNode *m = newNode->parent; while (m != NULL) {//go up //get maxHeight of left and right children int maxHeight = 0; if (m->left != NULL) { maxHeight = m->left->height; } if (m->right != NULL && maxHeight < m->right->height) { maxHeight = m->right->height; } //update height of m m->height = 1 + maxHeight; m = m->parent; } //at this point, the newnode is in place and height has been adjusted for correctness, //however, may not fulfill AVL tree conditions, because of potential height differences //in subtrees (ie difference in height of left and right > 1) //restructure beginning at inserted node //Find node to insert into //Node does not exist. Create it. //Height might not be valid anymore. //We need to restructure . if ( debug) { printf("---------- Before Restructure -----------------\n"); printNode("", root, 0); } // Call restructure restructure(newNode); if (debug) { checkRecursive(root); printf("---------- After Restructure -----------------\n"); printNode("", root, 0); } nElements++; return true; }
// If node X is a leaf or has only one child, skip to step 5. (node Z will be node X) // Otherwise, determine node Y by finding the largest node in node X's left sub tree (in-order predecessor) or the smallest in its right sub tree (in-order successor). // Replace node X with node Y (remember, tree structure doesn't change here, only the values). In this step, node X is essentially deleted when its internal values were overwritten with node Y's. // Choose node Z to be the old node Y. // Attach node Z's subtree to its parent (if it has a subtree). If node Z's parent is null, update root. (node Z is currently root) // Delete node Z. // Retrace the path back up the tree (starting with node Z's parent) to the root, adjusting the balance factors as needed. // As with all binary trees, a node's in-order successor is the left-most child of its right subtree, and a node's in-order predecessor is the right-most child of its left subtree. // In either case, this node will have zero or one children. Delete it according to one of the two simpler cases above. // Removes one element from the dictionary bool AVLDictionary::removeElement(KeyType key) { if (debug) { printf("------------------------------------\n"); printf("removeElement(\"%s\")\n", key); printf("---------- Before -----------------\n"); printNode("", root, 0); } //need to subsitute root with node that comes immediately before or after // AVLNode *current = (AVLNode*)findNode(key); AVLNode *current = root; while (current != NULL) { if (strcmp(current->key, key) == 0) { break; } else if (strcmp(current->key, key) > 0) { current = current->left; } else { current = current->right; } } if (current == NULL) { return false; } AVLNode *parent = NULL; if (current != root) { parent = current->parent; } else { //is root current->left = current->right->parent; } // if(current == parent->right) { // parent->right = current->right; // } else { // parent->left = current->right; // } if (current->left == NULL && current->right == NULL) { //no children, just delete? if (current == parent->right) { parent->right = NULL; } else { parent->left = NULL; } delete current; restructure(parent); } else if (current->left == NULL) { if (current == parent->right) { parent->right = NULL; parent->right = current->right; parent->right->height = current->right->height; delete current; current = NULL; restructure(parent); } else { parent->left = NULL; parent->left = current->right; parent->left->height = current->right->height; restructure(parent); delete current; current = NULL; } // restructure(current->right); } else if (current->right == NULL) { if (current == parent->right) { parent->right = NULL; parent->right = current->left; parent->right->height = current->left->height; // current = current->right; restructure(parent); delete current; current = NULL; } else { parent->left = NULL; parent->left = current->left; parent->left->height = current->left->height; restructure(parent); delete current; current = NULL; // current = current->right; } // delete current; // restructure(parent); // parent->left = current->right; // current = current->right; // restructure(current); // restructure(current->left); } else { //is internal AVLNode *preorder = current->left; while (preorder->right != NULL) { preorder = preorder->right; } current->key = preorder->key; current->data = preorder->data; current = preorder; if (current->left == NULL) { if (current->parent->right == current) { current->parent->right = current->right; } else { current->parent->left = current->right; } } else { if (current->parent->right == current) { current->parent->right = current->left; } else { current->parent->left = current->left; } } restructure(current->parent); delete current; } if (debug) { printf("---------- After -----------------\n"); printNode("", root, 0); checkRecursive(root); } return true; }
void writeFunc(char def[], int fid){ FILE *fp; const char delim1[3] = "(,)"; const char delim2[1] = " "; int saveCount = 0; char intSaver[100]; char receive[100], functionId[100], temp[50], trackerInt[50], trackerChar[50]; char *token, *sepInt, *endstr1, *endstr2; int i; //Delete the file (if exists) remove("temp.c"); //Parse definition and write to file fp = fopen("temp.c","a"); //Write definition fputs(def,fp); fputs("{\n",fp); //Split into send and receive token = strtok_r(def, delim1,&endstr1); i = 0; while(token != NULL){ if(i == 0){ //Save receive token strcpy(receive,token); //Write function Indentifier send if(strstr(receive,"int*") != NULL || strstr(receive,"char*") != NULL){ sprintf(functionId,"%s(%d)%s","if(sendInt",fid,"<0){\nputs(\"Send Failure\");\nreturn NULL;\n}\n"); }else{ sprintf(functionId,"%s(%d)%s","if(sendInt",fid,"<0){\nputs(\"Send Failure\");\nreturn -1;\n}\n"); } fputs(functionId,fp); fputs("\n",fp); }else{ //Add send code if(strstr(token,"int*") != NULL){ //Break the token sepInt = strtok_r(token,delim2,&endstr2); while(sepInt != NULL){ strcpy(temp,sepInt); sepInt = strtok_r(NULL, delim2,&endstr2); } //remeber the variable strcpy(trackerInt,temp); if(strstr(receive,"int*") != NULL || strstr(receive,"char*") != NULL){ sprintf(functionId,"%s(%s,%s)%s","if(sendIntArray",intSaver,temp,"<0){\nputs(\"Send Failure\");\nreturn NULL;\n}\n"); }else{ sprintf(functionId,"%s(%s,%s)%s","if(sendIntArray",intSaver,temp,"<0){\nputs(\"Send Failure\");\nreturn -1;\n}\n"); } fputs(functionId,fp); fputs("\n",fp); //Clear buff saveCount = 0; strcpy(intSaver,""); }else if(strstr(token,"int") != NULL){ //Break the token sepInt = strtok_r(token,delim2,&endstr2); while(sepInt != NULL){ strcpy(temp,sepInt); sepInt = strtok_r(NULL, delim2,&endstr2); } //Add to a buff if(saveCount < 2){ if(saveCount == 0){ strcpy(intSaver,""); strcat(intSaver,temp); saveCount++; }else{ strcat(intSaver,"*"); strcat(intSaver,temp); saveCount++; } }else{ restructure(intSaver); strcat(intSaver,"*"); strcat(intSaver,temp); } if(strstr(receive,"int*") != NULL || strstr(receive,"char*") != NULL){ sprintf(functionId,"%s(%s)%s","if(sendInt",temp,"<0){\nputs(\"Send Failure\");\nreturn NULL;\n}\n"); }else{ sprintf(functionId,"%s(%s)%s","if(sendInt",temp,"<0){\nputs(\"Send Failure\");\nreturn -1;\n}\n"); } fputs(functionId,fp); fputs("\n",fp); }else if(strstr(token,"char*") != NULL){ //Break the token sepInt = strtok_r(token,delim2,&endstr2); while(sepInt != NULL){ strcpy(temp,sepInt); sepInt = strtok_r(NULL, delim2,&endstr2); } //remeber the variable strcpy(trackerChar,temp); if(strstr(receive,"int*") != NULL || strstr(receive,"char*") != NULL){ sprintf(functionId,"%s(%d,%s)%s","if(sendString",2048,temp,"<0){\nputs(\"Send Failure\");\nreturn NULL;\n}\n"); }else{ sprintf(functionId,"%s(%d,%s)%s","if(sendString",2048,temp,"<0){\nputs(\"Send Failure\");\nreturn -1;\n}\n"); } fputs(functionId,fp); fputs("\n",fp); } } i++; token = strtok_r(NULL, delim1,&endstr1); } //Write Receive code if(strstr(receive,"int*") != NULL){ //get array size, declare new integer fputs("int num1;\n",fp); sprintf(functionId,"%s(%s)%s","if(readInt","num1","<0){\nputs(\"Receive Failure\");\nreturn NULL;\n}\n"); fputs(functionId,fp); //declare new array //fputs("int tempArray[num1];\n",fp); sprintf(functionId,"%s(%s,%s)%s","if(readIntArray","num1",trackerInt,"<0){\nputs(\"Receive Failure\");\nreturn NULL;\n}\n"); fputs(functionId,fp); sprintf(functionId,"%s %s;\n","return", trackerInt); fputs(functionId,fp); }else if(strstr(receive,"int") != NULL){ //declare new integer fputs("int num1;\n",fp); sprintf(functionId,"%s(%s)%s","if(readInt","num1","<0){\nputs(\"Receive Failure\");\nreturn -1;\n}\n"); fputs(functionId,fp); fputs("return num1;\n",fp); }else if(strstr(receive,"char*") != NULL){ //fputs("char tempString[100];\n",fp); sprintf(functionId,"%s(%d,%s)%s","if(readstring",2048,trackerChar,"<0){\nputs(\"Receive Failure\");\nreturn NULL;\n}\n"); fputs(functionId,fp); sprintf(functionId,"%s %s;\n","return", trackerChar); fputs(functionId,fp); //fputs("return tempString;\n",fp); } fputs("}",fp); //close file fclose(fp); //Write this file to the main stub write("temp.c","client_stub.c"); //Remove temp file after use remove("temp.c"); }