/* Delete Node */ ptr_t DeleteTreeNode(data_t *Master2Mem, data_t *Master2SysAlloc, ptr_t stackPtr, ptr_t rootPtr, int key){ struct search_t node2delete = Search(Master2Mem, rootPtr, key); if (node2delete.flag_failed != 1){ ptr_t nodePtr = node2delete.nodePtr; ptr_t leftPtr = tree_node_get_left_pointer(Master2Mem, nodePtr); ptr_t rightPtr = tree_node_get_right_pointer(Master2Mem, nodePtr); struct tree_ode2move; ptr_t tempPtr; if(leftPtr != NULL_PTR){ // copy contents of leftPtr to nodePtr, then free nodePtr tree_node_write_data(Master2Mem, nodePtr, tree_node_read_data(Master2Mem, leftPtr)); ptr_t left_leftPtr = tree_node_get_left_pointer(Master2Mem, leftPtr); tree_node_set_left(Master2Mem, nodePtr, left_leftPtr); ptr_t left_rightPtr = tree_node_get_right_pointer(Master2Mem, leftPtr); tree_node_set_right(Master2Mem, nodePtr, left_rightPtr); tree_node_delete(Master2SysAlloc, leftPtr); if(rightPtr != NULL_PTR){ if(left_rightPtr == NULL_PTR){ tree_node_set_right(Master2Mem, nodePtr, rightPtr); }else{ //insert new node with rightPtr node key value int rightNodeData = tree_node_read_data(Master2Mem, rightPtr); tempPtr = Insert(Master2Mem, Master2SysAlloc, stackPtr, rootPtr,rightNodeData); tree_node_write_data(Master2Mem, tempPtr, rightNodeData); ptr_t right_leftPtr = tree_node_get_left_pointer(Master2Mem, rightPtr); tree_node_set_left(Master2Mem, tempPtr, right_leftPtr); ptr_t right_rightPtr = tree_node_get_right_pointer(Master2Mem, rightPtr); tree_node_set_right(Master2Mem, tempPtr, right_rightPtr); } } }else if(rightPtr != NULL_PTR){ tree_node_write_data(Master2Mem, nodePtr, tree_node_read_data(Master2Mem, rightPtr)); ptr_t right_leftPtr = tree_node_get_left_pointer(Master2Mem, rightPtr); tree_node_set_left(Master2Mem, nodePtr, right_leftPtr); ptr_t right_rightPtr = tree_node_get_right_pointer(Master2Mem, rightPtr); tree_node_set_right(Master2Mem, nodePtr, right_rightPtr); tree_node_delete(Master2SysAlloc, rightPtr); }else{ // no children nodes // need to update the parent node's pointer tree_node_delete(Master2SysAlloc, nodePtr); if(node2delete.direction == GOING_LEFT){ tree_node_set_left(Master2Mem, node2delete.parentPtr, NULL_PTR); }else if(node2delete.direction == GOING_RIGHT){// right pointer need to be updated tree_node_set_right(Master2Mem, node2delete.parentPtr, NULL_PTR); }else{ //update root; rootPtr = NULL_PTR; } } } return rootPtr; }
void rb_tree_insert (RbTree *t, void *data) { TreeNode *x; TreeNode *y; TreeNode *z; assert (t != NULL); x = tree_node_get_right (t->sent); y = t->sent; z = tree_node_new_full (data, NULL, y, y); if (z == NULL) { return; } while (x != t->sent) { y = x; if (t->cmp_f (data, tree_node_get_content (x)) < 0) { x = tree_node_get_left (x); } else { x = tree_node_get_right (x); } } tree_node_set_parent (z, y); if (y == t->sent) /* root */ { tree_node_set_right (t->sent, z); } else { if (t->cmp_f (data, tree_node_get_content (y)) < 0) { tree_node_set_left (y, z); } else { tree_node_set_right (y, z); } } tree_node_set_red (z); rb_insert_fixup (t, z); (t->card)++; }
void rb_tree_flush (RbTree *t) { assert (t != NULL); _bin_tree_flush (tree_node_get_right (t->sent), t->sent); tree_node_set_right (t->sent, t->sent); t->card = 0; }
RbTree *rb_tree_new (compare_func_t cmp_f) { RbTree *t; assert (cmp_f != NULL); t = (RbTree *) Malloc (sizeof (RbTree)); if (t == NULL) { return NULL; } t->sent = tree_node_new_full (NULL, NULL, NULL, NULL); if (t->sent == NULL) { free (t); return NULL; } tree_node_set_right (t->sent, t->sent); tree_node_set_black (t->sent); t->card = 0; t->cmp_f = cmp_f; return t; }
void _bin_tree_insert_right (TreeNode *p, TreeNode *r) { assert (p != NULL); assert (r != NULL); tree_node_set_right (p, r); tree_node_set_parent (r, p); }
static void right_rotate (RbTree *t, TreeNode *x) { TreeNode *y; TreeNode *ry; TreeNode *px; assert (t != NULL); assert (x != NULL); /* Set y */ y = tree_node_get_left (x); assert (y != NULL); /* Turn y's right subtree into x's left subtree */ ry = tree_node_get_right (y); tree_node_set_left (x, ry); if (ry != t->sent) { tree_node_set_parent (ry, x); } /* Link x's parent to y */ px = tree_node_get_parent (x); tree_node_set_parent (y, px); if (px == t->sent) { tree_node_set_right (t->sent, y); } else { if (x == tree_node_get_left (px)) { tree_node_set_left (px, y); } else /* x == tree_node_get_right (px) */ { tree_node_set_right (px, y); } } /* Put x on y's right */ tree_node_set_right (y, x); tree_node_set_parent (x, y); }
/* Insert Node*/ ptr_t Insert(data_t *Master2Mem, data_t *Master2SysAlloc, ptr_t stackPtr, ptr_t treePtr, int data){ int flag_stackIsUsed = 0; int flag_stop = 0; struct sub_t subResult; struct stack_t stackOutput; ptr_t currentPtr = treePtr; ptr_t returnPtr; while(flag_stop == 0){ subResult = InsertSub(Master2Mem, Master2SysAlloc, currentPtr, data); if(subResult.feedback == FB_DONE){ flag_stop = 1; returnPtr = subResult.pointer; if(flag_stackIsUsed != 0){ stackOutput = dynamicStack(Master2Mem, Master2SysAlloc, stackPtr, READ_STACK, 0, 0); stackPtr = stackOutput.hdPtr; if(subResult.flag_same_key == 0){ // if same key doesn't exist, new node is inserted, hence the parrent node's offset needs to be updated if(stackOutput.operation == GOING_LEFT){ tree_node_set_left(Master2Mem, stackOutput.pointer, subResult.pointer); }else{ tree_node_set_right(Master2Mem, stackOutput.pointer, subResult.pointer); } } // read stack to clear stack while(stackPtr != NULL_PTR){ stackOutput = dynamicStack(Master2Mem, Master2SysAlloc, stackPtr, READ_STACK, 0, 0); stackPtr = stackOutput.hdPtr; } } }else{ flag_stackIsUsed = 1; if(subResult.feedback == FB_LEFT){ stackOutput = dynamicStack(Master2Mem, Master2SysAlloc, stackPtr, WRITE_STACK, currentPtr, GOING_LEFT); stackPtr = stackOutput.hdPtr; currentPtr = tree_node_get_left_pointer(Master2Mem, currentPtr); }else{ stackOutput = dynamicStack(Master2Mem, Master2SysAlloc, stackPtr, WRITE_STACK, currentPtr, GOING_RIGHT); stackPtr = stackOutput.hdPtr; currentPtr = tree_node_get_right_pointer(Master2Mem, currentPtr); } } } return returnPtr; }
/* Delete Tree */ ptr_t DeleteTree(data_t *Master2Mem, data_t *Master2SysAlloc, ptr_t stackPtr, ptr_t treePtr){ int flag_stackIsUsed = 0; int flag_stop = 0; struct sub_t subResult; struct stack_t stackOutput; ptr_t currentPtr = treePtr; ptr_t returnPtr; while(flag_stop == 0){ subResult = DeleteTreeSub(Master2Mem, Master2SysAlloc, currentPtr); if(subResult.feedback == FB_DONE){ if(flag_stackIsUsed == 0){ flag_stop = 1; returnPtr = subResult.pointer; }else{ if(stackPtr == NULL_PTR){ flag_stop = 1; returnPtr = subResult.pointer; }else{ stackOutput = dynamicStack(Master2Mem, Master2SysAlloc, stackPtr, READ_STACK, 0, 0); stackPtr = stackOutput.hdPtr; currentPtr = stackOutput.pointer; if(stackOutput.operation == GOING_LEFT){ tree_node_set_left(Master2Mem, stackOutput.pointer, subResult.pointer); }else{ tree_node_set_right(Master2Mem, stackOutput.pointer, subResult.pointer); } } } }else{ flag_stackIsUsed = 1; if(subResult.feedback == FB_LEFT){ stackOutput = dynamicStack(Master2Mem, Master2SysAlloc,stackPtr, WRITE_STACK, currentPtr, GOING_LEFT); stackPtr = stackOutput.hdPtr; currentPtr = subResult.pointer; }else{ stackOutput = dynamicStack(Master2Mem, Master2SysAlloc,stackPtr, WRITE_STACK, currentPtr, GOING_RIGHT); stackPtr = stackOutput.hdPtr; currentPtr = subResult.pointer; } } } return returnPtr; }
void *rb_tree_delete (RbTree *t, void *data) { TreeNode *x; /* y's not SENTINEL child, or SENTINEL if y don't have child */ TreeNode *y; /* the node actually delete */ TreeNode *z; /* the node contain data */ TreeNode *py; /* parent of y */ assert (t != NULL); z = _bin_tree_search (tree_node_get_right (t->sent), t->sent, t->cmp_f, data); if (z == NULL) { fprintf (stderr, "warning!, return an NULL\n"); return NULL; } if ((tree_node_get_left (z) == t->sent) || (tree_node_get_right (z) == t->sent)) { y = z; } else { y = _bin_tree_successor (z, t->sent); } if (tree_node_get_left (y) != t->sent) { x = tree_node_get_left (y); } else { x = tree_node_get_right (y); } py = tree_node_get_parent (y); tree_node_set_parent (x, py); if (py == t->sent) { tree_node_set_right (t->sent, x); } else { if (y == tree_node_get_left (py)) { tree_node_set_left (py, x); } else { tree_node_set_right (py, x); } } if (y != z) { tree_node_set_content (z, tree_node_get_content (y)); } if (tree_node_is_black (y)) { rb_delete_fixup (t, x); } tree_node_free (y); (t->card)--; return data; }