void delete_rec(struct node *root, unsigned int key) { if (root->key > key) { if (root->left == NULL) return; if (root->left->key == key) { root->left = delete_node(root->left); } else { delete_rec(root->left, key); set_height(root->left); root->left = rebalance(root->left); } } else { if (root->right == NULL) return; if (root->right->key == key) { root->right = delete_node(root->right); } else { delete_rec(root->right, key); set_height(root->right); root->right = rebalance(root->right); } } return; }
struct node *delete_node(struct node *root) { struct node *child, *aux; unsigned int key; if (root->left == NULL) { aux = root->right; free(root); return aux; } else if (root->right == NULL) { aux = root->left; free(root); return aux; } else { if (root->right->left == NULL) { child = root->right; root->value = child->value; root->key = child->key; root->right = child->right; free(child); } else { key = root->key; child = node_min(root->right); root->value = child->value; root->key = child->key; child->key = key; delete_rec(root, key); } set_height(root); return rebalance(root); } }
void bst_delete(bst_t *tree, int data) { if(tree == NULL || tree->head == NULL) { return; } else { //updates the head with the bottom of the stack from delete_rec tree->head = delete_rec(tree->head, data); } }
//deletes the node recursively bst_n* delete_rec(bst_n* node, int data) { //base case of an empty leaf if(node == NULL) { return node; } //determines which way to go in subtree if(data > node->data) { //updates right leaf with proper node, same for left node->right = delete_rec(node->right, data); //if no-leaf case then node->right will be updated to NULL so don't check parent if(node->right) { node->right->parent = node; } } else if(data < node->data) { node->left = delete_rec(node->left, data); if(node->left) { node->left->parent = node; } } else { bst_n *temp; //if both children exist then replace node with its inorder successor if(node->left && node->right) { temp = find_min(node->right); //replace the data rather than allocated a new node and updates its leaves node->data = temp->data; node->right = delete_rec(node->right, temp->data); //if only right node exists then return its leaf as new leaf for original node's parent } else if(node->right) { temp = node->right; free(node); return temp; //if only right node exists then return its leaf as new leaf for original node's parent } else if(node->left) { temp = node->left; free(node); return temp; //if no leaves delete the node and return an empty leaf for original node's parent } else { free(node); return NULL; } } //base case of an occupied leaf return node; }
void lemur::file::Keyfile::remove( const char* key ) { assert( key && "key cannot be null" ); assert( _handle && "call open() or create() first" ); int len = strlen(key); // fix for UTF-8 int error = delete_rec( _handle, const_cast<char*>(key), len ); if( error ) LEMUR_THROW( LEMUR_KEYFILE_IO_ERROR, "Unable to delete record for key: " + key ); }
void dict_delete(struct dictionary *d, unsigned int key) { if (d->root == NULL) return; if (d->root->key == key) { d->root = delete_node(d->root); } else { delete_rec(d->root, key); } set_height(d->root); d->root = rebalance(d->root); }
//deletes entire tree, just for clean up after unit tests void delete_tree(bst_t *tree) { while(tree->head != NULL) { tree->head = delete_rec(tree->head, tree->head->data); } free(tree); }
/******************************************************************** * * Search through all the child tracking records and see if * any can be shutdown. */ void mgr_shutdown_scan() { int i; long now; FILE *errlog; static int errlog_problem_notice = 0; Bool shutdown_time; for ( i = 0; i < g.serviceRecNum; i++ ) { shutdown_time = False; if ( (g.serviceRecs[i]->do_launch_reply) && (has_exec_token(g.serviceRecs[i]) ) ) { /* * Need to send our PDM_START fork/exec reply still. * * Note that if we send pdm_start_ok, we'll need to send * a pdm_exit_* code later. If we send pdm_start_vxauth, * pdm_start_pxauth, or pdm_start_error, it indicates to * the client a fatal condition, and they will NOT receive * any more messages, including any pdm_exit_* codes. The * dtpdmd will hang around however, if for no other reason * than to capture stderr and log it when the child finally * goes down. */ mgr_launch_reply( g.serviceRecs[i] ); g.serviceRecs[i]->do_launch_reply = False; /* it has been done */ } if ( (g.serviceRecs[i]->pdm_exec_errorcode == g.pdm_start_ok) && (g.serviceRecs[i]->exit_received) && (g.serviceRecs[i]->message_pipe[0] == -1) ) { /* * Child is down, and since we sent a pdm_start_ok, * we need to send a PDM_REPLY pdm_exit_* code too. */ mgr_shutdown_reply( g.serviceRecs[i] ); } if ( (g.serviceRecs[i]->exit_received) && (g.serviceRecs[i]->message_pipe[0] == -1) ) { /* * Child is down. Log any final error messages * from the child, and from the dtpdmd on behalf of * the child. */ if ( ((g.serviceRecs[i]->message_string) || (g.serviceRecs[i]->message_string2)) && (g.log_file) ) { if ((errlog = fopen(g.log_file, "a+")) != NULL) { now = time((time_t)0); fprintf (errlog, PDMD_MSG_14, g.prog_name, ctime(&now), g.serviceRecs[i]->pdm_exec_argvs[0], g.serviceRecs[i]->print_display_str, g.serviceRecs[i]->video_display_str, g.serviceRecs[i]->exit_code, g.serviceRecs[i]->message_string); if (g.serviceRecs[i]->message_string2) { fprintf (errlog, PDMD_MSG_15, g.serviceRecs[i]->message_string2); } fprintf (errlog, "\n"); fclose(errlog); } else if (!errlog_problem_notice) { fprintf (stderr, PDMD_MSG_16, g.prog_name, g.log_file ); fflush (stderr); errlog_problem_notice = 1; } } /* * The child is done and can be cleaned up. */ delete_rec( g.serviceRecs[i] ); } } }