📄 bistree.c
字号:
/***********************************************************************
* *
* Ensure that the tree remains balanced. *
* *
***********************************************************************/
if (!(*balanced)) {
switch (((AvlNode *)bitree_data(*node))->factor) {
case AVL_LFT_HEAVY:
rotate_left(node);
*balanced = 1;
break;
case AVL_BALANCED:
((AvlNode *)bitree_data(*node))->factor = AVL_LFT_HEAVY;
break;
case AVL_RGT_HEAVY:
((AvlNode *)bitree_data(*node))->factor = AVL_BALANCED;
*balanced = 1;
}
}
} /* if (cmpval < 0) */
else if (cmpval > 0) {
/***********************************************************************
* *
* Move to the right. *
* *
***********************************************************************/
if (bitree_is_eob(bitree_right(*node))) {
if ((avl_data = (AvlNode *)malloc(sizeof(AvlNode))) == NULL)
return -1;
avl_data->factor = AVL_BALANCED;
avl_data->hidden = 0;
avl_data->data = (void *)data;
if (bitree_ins_right(tree, *node, avl_data) != 0)
return -1;
*balanced = 0;
}
else {
if ((retval = insert(tree, &bitree_right(*node), data, balanced))
!= 0) {
return retval;
}
}
/***********************************************************************
* *
* Ensure that the tree remains balanced. *
* *
***********************************************************************/
if (!(*balanced)) {
switch (((AvlNode *)bitree_data(*node))->factor) {
case AVL_LFT_HEAVY:
((AvlNode *)bitree_data(*node))->factor = AVL_BALANCED;
*balanced = 1;
break;
case AVL_BALANCED:
((AvlNode *)bitree_data(*node))->factor = AVL_RGT_HEAVY;
break;
case AVL_RGT_HEAVY:
rotate_right(node);
*balanced = 1;
}
}
} /* if (cmpval > 0) */
else {
/***********************************************************************
* *
* Handle finding a copy of the data. *
* *
***********************************************************************/
if (!((AvlNode *)bitree_data(*node))->hidden) {
/********************************************************************
* *
* Do nothing since the data is in the tree and not hidden. *
* *
********************************************************************/
return 1;
}
else {
/********************************************************************
* *
* Insert the new data and mark it as not hidden. *
* *
********************************************************************/
if (tree->destroy != NULL) {
/*****************************************************************
* *
* Destroy the hidden data since it is being replaced. *
* *
*****************************************************************/
tree->destroy(((AvlNode *)bitree_data(*node))->data);
}
((AvlNode *)bitree_data(*node))->data = (void *)data;
((AvlNode *)bitree_data(*node))->hidden = 0;
/********************************************************************
* *
* Do not rebalance because the tree structure is unchanged. *
* *
********************************************************************/
*balanced = 1;
}
}
}
return 0;
}
/*****************************************************************************
* *
* --------------------------------- hide --------------------------------- *
* *
*****************************************************************************/
static int hide(BisTree *tree, BiTreeNode *node, const void *data) {
int cmpval,
retval;
if (bitree_is_eob(node)) {
/**************************************************************************
* *
* Return that the data was not found. *
* *
**************************************************************************/
return -1;
}
cmpval = tree->compare(data, ((AvlNode *)bitree_data(node))->data);
if (cmpval < 0) {
/**************************************************************************
* *
* Move to the left. *
* *
**************************************************************************/
retval = hide(tree, bitree_left(node), data);
}
else if (cmpval > 0) {
/**************************************************************************
* *
* Move to the right. *
* *
**************************************************************************/
retval = hide(tree, bitree_right(node), data);
}
else {
/**************************************************************************
* *
* Mark the node as hidden. *
* *
**************************************************************************/
((AvlNode *)bitree_data(node))->hidden = 1;
retval = 0;
}
return retval;
}
/*****************************************************************************
* *
* -------------------------------- lookup -------------------------------- *
* *
*****************************************************************************/
static int lookup(BisTree *tree, BiTreeNode *node, void **data) {
int cmpval,
retval;
if (bitree_is_eob(node)) {
/**************************************************************************
* *
* Return that the data was not found. *
* *
**************************************************************************/
return -1;
}
cmpval = tree->compare(*data, ((AvlNode *)bitree_data(node))->data);
if (cmpval < 0) {
/**************************************************************************
* *
* Move to the left. *
* *
**************************************************************************/
retval = lookup(tree, bitree_left(node), data);
}
else if (cmpval > 0) {
/**************************************************************************
* *
* Move to the right. *
* *
**************************************************************************/
retval = lookup(tree, bitree_right(node), data);
}
else {
if (!((AvlNode *)bitree_data(node))->hidden) {
/***********************************************************************
* *
* Pass back the data from the tree. *
* *
***********************************************************************/
*data = ((AvlNode *)bitree_data(node))->data;
retval = 0;
}
else {
/***********************************************************************
* *
* Return that the data was not found. *
* *
***********************************************************************/
return -1;
}
}
return retval;
}
/*****************************************************************************
* *
* ----------------------------- bistree_init ----------------------------- *
* *
*****************************************************************************/
void bistree_init(BisTree *tree, int (*compare)(const void *key1, const void
*key2), void (*destroy)(void *data)) {
/*****************************************************************************
* *
* Initialize the tree. *
* *
*****************************************************************************/
bitree_init(tree, destroy);
tree->compare = compare;
return;
}
/*****************************************************************************
* *
* ---------------------------- bistree_destroy --------------------------- *
* *
*****************************************************************************/
void bistree_destroy(BisTree *tree) {
/*****************************************************************************
* *
* Destroy all nodes in the tree. *
* *
*****************************************************************************/
destroy_left(tree, NULL);
/*****************************************************************************
* *
* No operations are allowed now, but clear the structure as a precaution. *
* *
*****************************************************************************/
memset(tree, 0, sizeof(BisTree));
return;
}
/*****************************************************************************
* *
* ---------------------------- bistree_insert ---------------------------- *
* *
*****************************************************************************/
int bistree_insert(BisTree *tree, const void *data) {
int balanced = 0;
return insert(tree, &bitree_root(tree), data, &balanced);
}
/*****************************************************************************
* *
* ---------------------------- bistree_remove ---------------------------- *
* *
*****************************************************************************/
int bistree_remove(BisTree *tree, const void *data) {
return hide(tree, bitree_root(tree), data);
}
/*****************************************************************************
* *
* ---------------------------- bistree_lookup ---------------------------- *
* *
*****************************************************************************/
int bistree_lookup(BisTree *tree, void **data) {
return lookup(tree, bitree_root(tree), data);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -