User_Node user_successor(User_Node node) { RBTNode rbt = rbt_successor(node->rbtnode); if (rbt == NULL) return NULL; else return (User_Node)rbt->data; }
void rbt_inorder(rbtree_t * T,void (*visit)(rbnode_t *)) { rbnode_t *x; x = T->root; if (x != &T->nil) { x = rbt_min(T,x); while (x != 0) { visit(x); x = rbt_successor(T,x); } } return ; }
// 删除一个结点 // 考虑的情况 // 空树:该情况不可能出现,因为y已经指向树中的某一结点 // 只有一个根节点的树 // 有多个结点的树 prbtree rbt_delete_node(prbtree T, prbt_node z) { // y指向要删除的结点 prbt_node y; prbt_node x; if (z->left == nil || z->right == nil) { y = z; } else { y = rbt_successor(z); } // x 指向要连接的子树 if (y->left != nil) { x = y->left; } else { x = y->right; } x->parent = y->parent; if (y->parent == nil) { T = x; } else if (y->parent->left == y) { y->parent->left = x; } else { y->parent->right = x; } // 如果y != z 则y为z的后继结点,将z的key赋值为y的key if (y != z) { z->key = y->key; // 将z的卫星数据赋值为y的卫星数据 // ... } if (y->color == BLACK) { T = rbt_delete_fixup(T, x); } return T; }
void tweet_print_top_5_most_users() { if (user_database == NULL || user_database == Nil) { printf("트윗 데이터베이스가 비어있습니다.\n"); return; } char user[6][1000] = { "" }; int maxNum[6] = { 0 }; User_Node now = (User_Node)rbt_min_node(user_database)->data; User_Node max = (User_Node)rbt_max_node(user_database)->data; do { maxNum[5] = get_tweet_number_of_user(now); strcpy(user[5], now->name); for (int i = 0; i <5; i++) for (int j = i + 1; j < 6; j++) if (maxNum[i] < maxNum[j]) { int tmp = maxNum[i]; maxNum[i] = maxNum[j]; maxNum[j] = tmp; char tmpStr[100]; strcpy(tmpStr, user[i]); strcpy(user[i], user[j]); strcpy(user[j], tmpStr); } maxNum[5]++; now = (User_Node)rbt_successor(now->rbtnode)->data; } while (now != max); for (int i = 0; i < 5; i++) { printf("%d위 : %-20s - %2d번\n", i + 1, user[i], maxNum[i]); } }
//free node, return val void * delete_node(struct rbtree *rbt, struct rbnode *nd) { void *val = NULL; struct rbnode *ret = nd; struct rbnode *tmp, *itor; if (nd == NULL || rbt == NULL) return NULL; val = nd->key; //pthread_mutex_lock(&(rbt->lock)); if (nd->left == &rbt->nil || nd->right == &rbt->nil) tmp = nd; else tmp = rbt_successor(rbt, nd); if (tmp->left != &rbt->nil) itor = tmp->left; else itor = tmp->right; itor->parent = tmp->parent; if (tmp->parent == &rbt->nil) rbt->root = itor; else { if (tmp == tmp->parent->left) tmp->parent->left = itor; else tmp->parent->right = itor; } if (tmp != itor) nd->key = tmp->key; if (tmp->color == BLACK) delete_fixup(rbt, itor); if (ret == NULL) printf("ret is null\n"); free(tmp); rbt->size--; //pthread_mutex_unlock(&(rbt->lock)); return val; }
//free node, return val void * delete_node(struct rbtree *rbt, void *key) { void *val = NULL; struct rbnode *nd = NULL; struct rbnode *tmp, *itor; nd = find_node(rbt, key); if (nd == NULL || rbt == NULL) { printf("find node error\n"); return NULL; } val = nd->key; if (nd->left == &rbt->nil || nd->right == &rbt->nil) tmp = nd; else tmp = rbt_successor(rbt, nd); if (tmp->left != &rbt->nil) itor = tmp->left; else itor = tmp->right; itor->parent = tmp->parent; if (tmp->parent == &rbt->nil) rbt->root = itor; else { if (tmp == tmp->parent->left) tmp->parent->left = itor; else tmp->parent->right = itor; } if (tmp != itor) nd->key = tmp->key; if (tmp->color == BLACK) delete_fixup(rbt, itor); //free(tmp); rbt->size--; return tmp; }
RBT_NODE *rbt_remove( RBT_ROOT *root , RBT_NODE *z ) { RBT_NODE *x ; RBT_NODE *y ; if ( z == &( root->nil ) ) { return NULL ; } HQTRACE( rbt_debug , ( "rbt_remove: [%x] %x" , root , z->key )) ; if ( z->left == &( root->nil ) || z->right == &( root->nil ) ) { y = z ; } else { y = rbt_successor( root , z ) ; } HQASSERT( y != NULL , "Should rbt_successor return NULL?" ) ; if ( y->left != &( root->nil ) ) { x = y->left ; } else { x = y->right ; } x->p = y->p ; if ( y->p == &( root->nil ) ) { root->node = x ; } else { if ( y == y->p->left ) { y->p->left = x ; } else { y->p->right = x ; } } if ( y != z ) { uintptr_t tk ; void *td ; /* The example pseudo-code just copies data and "other fields" from y to z. That's not good enough when any one of them is a pointer: we end up with one data struct being doubly referenced and the other one orphaned. Solution: swap the pointers instead. */ tk = z->key ; z->key = y->key ; y->key = tk ; td = z->data ; z->data = y->data ; y->data = td ; } if ( y->red == FALSE ) { rbt_remove_fixup( root , x ) ; } root->count-- ; rbt_validate( root , root->node , NULL ) ; return y ; }