I've been trying to implement a function in C that deletes a node in a binary tree that should (theoretically) take care of three all cases, i.e.:
Node is a leaf
Node has one child
Node has two children
Is there a way to handle the whole deletion function without checking separately each case? As a commenter below noted I do check for a lot of cases and perhaps the whole problem can be addressed recursively by checking for one fundamental case.
I'm particularly interested in the case where I delete a node within the tree that has a parent and itself is a parent of two children nodes.
Both answers below have been useful but I don't think they address the problem in its entirety.
Here's what I have:
typedef struct Node
{
int key;
int data;
struct Node *left;
struct Node *right;
struct Node *parent;
} Node;
/* functions that take care of inserting and finding a node and also traversing and freeing the tree */
...
void delete(Node *root, int key)
{
Node *target = find(root, key); // find will return the node to be deleted
Node *parent = target->parent; // parent of node to be deleted
// no children
if (target->left == NULL && target->right == NULL)
{
// is it a right child
if (target->key > parent->key)
parent->right = NULL;
// must be a left child
else
parent->left = NULL;
free(target);
}
// one child
else if ((target->left == NULL && target->right != NULL) || (target->left != NULL && target->right == NULL))
{
// here we swap the target and the child of that target, then delete the target
Node *child = (target->left == NULL) ? target->right : target->left;
child->parent = parent;
if (parent->left == target) parent->left = child;
else if (parent->right == target) parent->right = child;
free(target);
}
// two children
else
{
// find the largest node in the left subtree, this will be the node
// that will take the place of the node to be deleted
Node *toBeRepl = max(target->left);
// assign the data of the second largest node
target->key = toBeRepl->key;
target->data = toBeRepl->data;
// if new node immediately to the left of target
if (toBeRepl == target->left)
{
target->left = toBeRepl->left;
Node *newLeft = target->left;
if (newLeft != NULL) newLeft->parent = target;
}
else
{
delete(target->left, toBeRepl->key);
// Node *replParent = toBeRepl->parent;
// replParent->right = NULL;
}
}
I would greatly appreciate your feedback.
edit: Just to clarify, I'm trying to delete a particular node without touching its subtrees (if there are any). They should remain intact (which I've handled by swapping the values of the node to be deleted and (depending on the case) one of the nodes of its substrees).
edit: I've used as a reference the following wikipedia article:
http://en.wikipedia.org/wiki/Binary_search_tree#Deletion
Which is where I got the idea for swapping the nodes values in case of two children, particularly the quote:
Call the node to be deleted N. Do not delete N. Instead, choose either
its in-order successor node or its in-order predecessor node, R.
Replace the value of N with the value of R, then delete R.
There is some interesting code in C++ there for the above case, however I'm not sure how exactly the swap happens:
else //2 children
{
temp = ptr->RightChild;
Node<T> *parent = nullptr;
while(temp->LeftChild!=nullptr)
{
parent = temp;
temp = temp->LeftChild;
}
ptr->data = temp->data;
if (parent!=nullptr)
Delete(temp,temp->data);
else
Delete(ptr->rightChild,ptr->RightChild->data);
}
Could somebody please explain what's going on in that section? I'm assuming that the recursion is of a similar approach as to the users comments' here.
I don't see any "inelegance" in the code, such formatting and commented code is hard to come by. But yes, you could reduce the if-else constructs in your delete function to just one case. If you look at the most abstract idea of what deletion is doing you'll notice all the cases basically boil down to just the last case (of deleting a node with two children).
You'll just have to add a few lines in it. Like after toBeRepl = max(left-sub-tree), check if it's NULL and if it is then toBeRepl = min(right-sub-tree).
So, Case 1 (No children): Assuming your max() method is correctly implemented, it'll return NULL as the rightmost element on the left sub-tree, so will min() on the right sub-tree. Replace your target with the toBeRepl, and you'll have deleted your node.
Case 2 (One child): If max() does return NULL, min() won't, or vice-versa. So you'll have a non-NULL toBeRepl. Again replace your target with this new toBeRepl, and you're done.
Case 3 (Two children): Same as Case 2, only you can be sure max() won't return NULL.
Therefore your entire delete() function would boil down to just the last else statement (with a few changes). Something on the lines of:
Node *toBeRepl = max(target->left);
if toBeRepl is NULL
{
toBeRepl = min(target->right);
}
if toBeRepl is not NULL
{
target->key = tobeRepl->key;
target->data = toBeRepl->data;
deallocate(toBeRepl); // deallocate would be a free(ptr) followed by setting ptr to NULL
}
else
{
deallocate(target);
}
I would do it using recursion, assuming that you have null at the end of your tree, finding null would be the 'go back' or return condition.
One possible algorithm would be:
Node* delete(Node *aNode){
if(aNode->right != NULL)
delete(aNode->right);
if(aNode->left != NULL)
delete(aNode->left);
//Here you're sure that the actual node is the last one
//So free it!
free(aNode);
//and, for the father to know that you're now empty, must return null
return NULL;
}
It has some bugs, for sure, but is the main idea.
This implementation is dfs like.
Hope this helps.
[EDIT] Node *aNode fixed. Forgot the star, my bad.
I finished this a long time ago and I thought it would be good to add a sample answer for people coming here with the same problem (considering the 400+ views this question has accumulated):
/* two children */
else
{
/* find the largest node in the left subtree (the source), this will be the node
* that will take the place of the node to be deleted */
Node* source = max(target->left);
/* assign the data of that node to the one we originally intended to delete */
target->key = source->key;
target->data = source->data;
/* delete the source */
delete(target->left, source->key);
}
Wikipedia has an excellent article that inspired this code.
Related
Now, I understand that code below works only for root and its children, but I don't know how to expand it. Every node must have children before passing on "grandchildren". Thank you.
void insert_node(IndexTree **root, Node *node) {
IndexTree *temp = (IndexTree*)malloc(sizeof(IndexTree));
memcpy(&temp->value.cs, node, sizeof(Node));
temp->left = NULL;
temp->right = NULL;
temp->tip=1;
if ((*root) == NULL) {
*root = temp;
(*root)->left = NULL;
(*root)->right = NULL;
}
else {
while (1) {
if ((*root)->right == NULL) {
(*root)->right = temp;
break;
}
else if ((*root)->left == NULL) {
(*root)->left = temp;
break;
}
}
}
Use recursive functions.
Trees are recursive data types (https://en.wikipedia.org/wiki/Recursive_data_type). In them, every node is the root of its own tree. Trying to work with them using nested ifs and whiles is simply going to limit you on the depth of the tree.
Consider the following function: void print_tree(IndexTree* root).
An implementation that goes over all values of the trees does the following:
void print_tree(IndexTree* root)
{
if (root == NULL) return; // do NOT try to display a non-existent tree
print_tree(root->right);
printf("%d\n", root->tip);
print_tree(root->left);
}
The function calls itself, which is a perfectly legal move, in order to ensure that you can parse an (almost) arbitrarily deep tree. Beware, however, of infinite recursion! If your tree has cycles (and is therefore not a tree), or if you forget to include an exit condition, you will get an error called... a Stack Overflow! Your program will effectively try to add infinite function calls on the stack, which your OS will almost certainly dislike.
As for inserting, the solution itself is similar to that of printing the tree:
void insert_value(IndexTree* root, int v)
{
if (v > root->tip) {
if (root->right != NULL) {
insert_value(root->right, v);
} else {
// create node at root->right
}
} else {
// same as above except with root->left
}
}
It may be an interesting programming question to create a Complete Binary Tree using linked representation. Here Linked mean a non-array representation where left and right pointers(or references) are used to refer left and right children respectively. How to write an insert function that always adds a new node in the last level and at the leftmost available position?
To create a linked complete binary tree, we need to keep track of the nodes in a level order fashion such that the next node to be inserted lies in the leftmost position. A queue data structure can be used to keep track of the inserted nodes.
Following are steps to insert a new node in Complete Binary Tree. (Right sckewed)
1. If the tree is empty, initialize the root with new node.
2. Else, get the front node of the queue.
……. if the right child of this front node doesn’t exist, set the right child as the new node. //as per your case
…….else If the left child of this front node doesn’t exist, set the left child as the new node.
3. If the front node has both the left child and right child, Dequeue() it.
4. Enqueue() the new node.
I am building an AVL tree, using this structure:
typedef struct node* nodep;
typedef struct node {
int postal_number;
int h; /* height */
nodep left, right, parent;
} Node;
Everything is working great: rotating, searching and inserting. The problem is with deleting a node. It deletes most of the node, except for few leaves after deleting most of the tree. My delete code (the problematic part) is:
int delete_postal(nodep* t, int in_postal){
nodep to_delete;
nodep* the_parent;
to_delete = search_postal((*t), in_postal);
the_parent = &(to_delete->parent);
/** if the node we want to delete is a leave **/
if (to_delete->right == NULL && to_delete->left == NULL) {
if (to_delete == (*the_parent)->right){ /* the node we want to delete is right son */
(*the_parent)->right = to_delete->right;
else { /* the node we want to delete is left son */
(*the_parent)->left = to_delete->left;
}
I made it so (*the_parent) will be the node himself in the tree, and when debugging it stepping into the if, it acts as if it did the deletion (making the child of the node the child of the node's father - I'm not dealing with malloc right now), but it just does not do it. The father keeps on pointing to the node that I would like to delete and not to NULL.
All the rest of the first deletion (nodes and leaves) works fine with this syntax.
Does somebody know what I am missing?
I'm now implementing Barnes-Hut Algorithms for simulating N-body problem. I only want to ask about the building-tree part.
There are two functions I made to build the tree for it.
I recursively build the tree, and print the data of each node while building and everything seems correct, but when the program is back to the main function only the root of the tree and the child of the root stores the value. Other nodes' values are not stored, which is weird since I printed them during the recursion and they should have been stored.
Here's some part of the code with modification, which I thought where the problem might be in:
#include<...>
typedef struct node{
int data;
struct node *child1,*child2;
}Node;
Node root; // a global variable
int main(){
.
set_root_and_build(); // is called not only once cuz it's actually in a loop
traverse(&root);
.
}
Here's the function set_root_and_build():
I've set the child pointers to NULL, but didn't show it at first.
void set_root_and_build(){
root.data = ...;
..// set child1 and child2 =NULL;
build(&root,...); // ... part are values of data for it's child
}
And build:
void build(Node *n,...){
Node *new1, *new2 ;
new1 = (Node*)malloc(sizeof(Node));
new2 = (Node*)malloc(sizeof(Node));
... // (set data of new1 and new2 **,also their children are set NULL**)
if(some condition holds for child1){ // else no link, so n->child1 should be NULL
build(new1,...);
n->child1 = new1;
//for debugging, print data of n->child1 & and->child2
}
if(some condition holds for child2){ // else no link, so n->child2 should be NULL
build(new2,...);
n->child1 = new2;
//for debugging, print data of n->child1 & and->child2
}
}
Nodes in the tree may have 1~2 children, not all have 2 children here.
The program prints out the correct data when it's in build() function recursion, but when it is back to main function and calls traverse(), it fails due to a segmentation fault.
I tried to print everything in traverse() and found that only the root, and root.child1, root.child2 stores the value just as what I've mentioned.
Since I have to called build() several times, and even in parallel, new1 and new2 can't be defined as global variables. (but I don't think they cause the problem here).
Does anyone know where it goes wrong?
The traverse part with debugging info:
void traverse(Node n){
...//print out data of n
if(n.child1!=NULL)
traverse(*(n.child1))
...//same for child2
}
You may not be properly setting the children of n when the condition does not hold. You might want this instead:
void set_root_and_build()
{
root.data = ...;
build(&root,...); // ... part are values of data for it's child
}
void build(Node *n,...)
{
n->child1 = n->child2 = NULL;
Node *new1, *new2;
new1 = (Node*) malloc(sizeof(Node));
new2 = (Node*) malloc(sizeof(Node));
// set data of new1 and new2 somehow (read from stdin?)
if (some condition holds for new1)
{
n->child1 = new1;
build(n->child1,...);
//for debugging, print data of n->child1
}
else
free(new1); // or whatever else you need to do to reclaim new1
if (some condition holds for new2)
{
n->child2 = new2;
build(n->child2,...);
//for debugging, print data of n->child2
}
else
free(new2); // or whatever else you need to do to reclaim new2
}
Of course, you should be checking the return values of malloc() and handling errors too.
Also, your traversal is a bit strange as it recurses by copy rather than reference. Do you have a good reason for doing that? If not, then maybe you want:
void traverse(Node *n)
{
...//print out data of n
if (n->child1 != NULL)
traverse(n->child1)
...//same for child2
}
The problem in your tree traversal is that you certainly process the tree until you find a node pointer which is NULL.
Unfortunately when you create the nodes, these are not initialized neither with malloc() nor with new (it would be initialized with calloc() but this practice in cpp code is as bad as malloc()). So your traversal continues to loop/recurse in the neverland of random pointers.
I propose you to take benefit of cpp and change slightly your structure to:
struct Node { // that's C++: no need for typedef
int data;
struct node *child1,*child2;
Node() : data(0), child1(nullptr), child2(nullptr) {} // Makes sure that every created are first initalized
};
And later get rid of your old mallocs. And structure the code to avoid unnecessary allocations:
if(some condition holds for child1){ // else no link, so n->child1 should be NULL
new1=new Node; // if you init it here, no need to free in an else !!
build(new1,...);
n->child1 = new1;
...
}
if (... child2) { ... }
Be aware however that poitners allocated with new should be released with delete and note with free().
Edit: There is a mismatch in your code snippet:
traverse(&root); // you send here a Node*
void traverse(Node n){ // but your function defines an argument by value !
...
}
Check that you didn't overllok some warnings from the compiler, and that you have no abusive cast in your code.
How to traverse each node of a tree efficiently without recursion in C (no C++)?
Suppose I have the following node structure of that tree:
struct Node
{
struct Node* next; /* sibling node linked list */
struct Node* parent; /* parent of current node */
struct Node* child; /* first child node */
}
It's not homework.
I prefer depth first.
I prefer no additional data struct needed (such as stack).
I prefer the most efficient way in term of speed (not space).
You can change or add the member of Node struct to store additional information.
If you don't want to have to store anything, and are OK with a depth-first search:
process = TRUE;
while(pNode != null) {
if(process) {
//stuff
}
if(pNode->child != null && process) {
pNode = pNode->child;
process = true;
} else if(pNode->next != null) {
pNode = pNode->next;
process = true;
} else {
pNode = pNode->parent;
process = false;
}
}
Will traverse the tree; process is to keep it from re-hitting parent nodes when it travels back up.
Generally you'll make use of a your own stack data structure which stores a list of nodes (or queue if you want a level order traversal).
You start by pushing any given starting node onto the stack. Then you enter your main loop which continues until the stack is empty. After you pop each node from the stack you push on its next and child nodes if not empty.
This looks like an exercise I did in Engineering school 25 years ago.
I think this is called the tree-envelope algorithm, since it plots the envelope of the tree.
I can't believe it is that simple. I must have made an oblivious mistake somewhere.
Any mistake regardless, I believe the enveloping strategy is correct.
If code is erroneous, just treat it as pseudo-code.
while current node exists{
go down all the way until a leaf is reached;
set current node = leaf node;
visit the node (do whatever needs to be done with the node);
get the next sibling to the current node;
if no node next to the current{
ascend the parentage trail until a higher parent has a next sibling;
}
set current node = found sibling node;
}
The code:
void traverse(Node* node){
while(node!=null){
while (node->child!=null){
node = node->child;
}
visit(node);
node = getNextParent(Node* node);
}
}
/* ascend until reaches a non-null uncle or
* grand-uncle or ... grand-grand...uncle
*/
Node* getNextParent(Node* node){
/* See if a next node exists
* Otherwise, find a parentage node
* that has a next node
*/
while(node->next==null){
node = node->parent;
/* parent node is null means
* tree traversal is completed
*/
if (node==null)
break;
}
node = node->next;
return node;
}
You can use the Pointer Reversal method. The downside is that you need to save some information inside the node, so it can't be used on a const data structure.
You'd have to store it in an iterable list. a basic list with indexes will work. Then you just go from 0 to end looking at the data.
If you want to avoid recursion you need to hold onto a reference of each object within the tree.
I kinda have to put my previous C questions on hold cause this one is more important now...
I have already coded the insert and delete functions on my binary search tree but the delete function is incomplete. There's a couple of things I need help in...
1) Is my insert function good or can it be improved somehow?
2) My delete function lacks the deletion of a node with both the left and right childs. I've searched a lot in the past few hours but couldn't find a proper way to do it.
2.a) How should I delete a node with 2 child nodes?
2.b) As in the first question, is the delete function good or can it be improved? This one I know it can because I'm repeating lots of code in those ifs but I don't see how can I improve it, I need help on that too.
typedef struct sClientProfile *ClientProfile;
typedef struct sClientTree *ClientTree;
typedef struct sClientProfile {
char *clientName;
int clientAge;
int clientNIF;
} nClientProfile;
typedef struct sClientTree {
ClientProfile clientProfile;
char *clientName;
ClientTree leftTree;
ClientTree rightTree;
} nClientTree;
void addClientToTree(ClientTree *cTree, ClientProfile cProfile) {
if(!*cTree) {
ClientTree new = (ClientTree)malloc(sizeof(nClientTree));
if(!new) {
perror("malloc");
}
new->clientName = strdup(cProfile->clientName);
new->clientProfile = cProfile;
new->leftTree = NULL;
new->rightTree = NULL;
*cTree = new;
} else {
if(strcmp((*cTree)->clientName, cProfile->clientName) > 0) {
addClientToTree(&(*cTree)->leftTree, cProfile);
} else {
addClientToTree(&(*cTree)->rightTree, cProfile);
}
}
}
void deleteClientFromTree(ClientTree *cTree, char *cName) {
if(!cTree) return;
int nCompare = strcmp((*cTree)->clientName, cName);
if(nCompare > 0) {
deleteClientFromTree(&(*cTree)->leftTree, cName);
} else if(nCompare < 0) {
deleteClientFromTree(&(*cTree)->rightTree, cName);
} else {
if(!(*cTree)->leftTree && !(*cTree)->rightTree) {
ClientTree cliPtr = *cTree;
free(cliPtr->clientProfile);
free(cliPtr);
cliPtr->clientProfile = NULL;
cliPtr = NULL;
*cTree = NULL;
} else if(!(*cTree)->leftTree) {
ClientTree cliPtr = *cTree;
free(cliPtr->clientProfile);
free(cliPtr);
cliPtr->clientProfile = NULL;
*cTree = (*cTree)->rightTree;
} else if(!(*cTree)->rightTree) {
ClientTree cliPtr = *cTree;
free(cliPtr->clientProfile);
free(cliPtr);
cliPtr->clientProfile = NULL;
*cTree = (*cTree)->leftTree;
} else {
// MISSING DELETE CASE
}
}
}
You'll probably notice but let me just make 2 remarks:
This tree uses strings instead of the normal int representation. That's why I use strcmp() all the way, I think I'm using it right.
I'm not using recursion, I rather pass the pointer (of a structure pointer in this case) and work with that. It looks more clean somehow and in the future I want to return a success value if a node was deleted.
UPDATE BELOW:
I've already did my iterative version of the delete function but I don't like some things about it, maybe they can be improved (or not) but I can't see how. I've also tried to code the case it was missing, deleting a node with 2 childs, but it's not working as it should...
I've commented the whole code where I think the code can be improved and where's the problem. I've also named those problems as A, B (there's no B anymore), C and D so we can reference to them easily.
bool deleteClientFromTree(ClientTree *cTree, char *cName) {
if(!cTree) return FALSE;
ClientTree currPtr = *cTree;
ClientTree prevPtr = NULL;
int nCompare;
while(currPtr) {
nCompare = strcmp(currPtr->clientName, cName);
if(nCompare > 0) {
prevPtr = currPtr;
currPtr = currPtr->leftTree;
} else if(nCompare < 0) {
prevPtr = currPtr;
currPtr = currPtr->rightTree;
} else {
/*
* A)
*
* The following cases have 3 lines in common, the free()
* calls and return statement. Is there anyway to improve
* this code and make it more compact?
*
* Of course, the printf's are to be removed...
*/
if(!prevPtr && !currPtr->leftTree && !currPtr->rightTree) {
printf("CASE #1\n");
*cTree = NULL;
free(currPtr->clientProfile);
free(currPtr);
return TRUE;
} else if(!currPtr->leftTree || !currPtr->rightTree) {
printf("CASE #2\n");
if(prevPtr->leftTree == currPtr) {
prevPtr->leftTree = currPtr->rightTree;
} else {
prevPtr->rightTree = currPtr->leftTree;
}
free(currPtr->clientProfile);
free(currPtr);
return TRUE;
} else {
printf("CASE #3\n");
ClientTree tempPtr = currPtr->rightTree;
while(tempPtr->leftTree) {
tempPtr = tempPtr->leftTree;
}
/*
* C)
*
* This has a big problem...
*
* If you take a look at the ClientProfile structure,
* in the first post, you'll see two ints
* (clientNIF/clientAge) and one char* (clientName).
*
* The problem is that the following code line is only
* copying the integer data, not the string. For some
* reason, the string remains the old one.
*
* I tried to use strdup() directly on clientName like:
* currPtr->clientProfile->clientName = strdup(tempPtr->clientProfile->clientName);
* but it still doesn't work.
*
* Why everything is being copied but the strings?
*/
currPtr->clientProfile = tempPtr->clientProfile;
/*
* D)
*
* Is there anyway to not call the function itself
* and make the while loop once again and delete the
* corresponding leaf?
*/
return deleteClientFromTree(&currPtr->rightTree, tempPtr->clientProfile->clientName);
}
}
}
return FALSE;
}
When you delete a node, you have to do something about its children.
If there are no children - no problem. You just remove the node.
If there a left child, also no problem; you remove the node and move its left child into its place.
Same for the right child; just move the child into the place of the deleted node.
The problem comes when you want to delete a node which has both left and right children. You could move the left or the right child into the place of the deleted node, but what do you then do about the other child and its subtree?
Solution is this; you locate the logical successor to the node being deleted. By logical successor, I mean this; say you have a tree made of integers and you delete node with value 35, the logical successor is the next largest number. Ya? if you were doing an in-order walk, it would be the element you come to after the element you're deleting.
Now, there's a simple rule to find the logical successor; you go right one (you always have a right, because this is the case where you have two children) and then you go as far left as you can.
That element you end up at is the logical successor. It's larger than the deleted element (you went right at the start, remember?) but it's the smallest next largest element.
Now, that element ALWAYS has only one or no children - because you went left as far as you can, remember? so you can't go left any more - because there is no left - so that element has no children or just a right child and that means it falls into one of the easy-to-unlink catagories (no children or just one child). So unlinking this element is easy.
Now comes the cool bit - consider this; if that next largest element were in the same place in the tree as the element you want to delete, the tree would still be valid and correct - because everything to the left of each element is smaller, everything to the right is larger.
So what you do is this; you copy the user data in the next largest node into the node being deleted and you delete that next largest node (it has no children or just a right child, so it's easy to unlink and delete).
And that's it!
So, basically - find your logical successor, unlink him from the tree and put his user data into the element you're actually originally deleting (which you don't then delete, of course, because it's still physically part of the tree).
First off, you mentioned you aren't using recursion but each function has a logical path that calls itself.
On to the questions:
1)
Remove the recursion. This can get you in a lot of trouble if your tree is large enough to blow your stack. Gcc has limited support for tail recursion, but I wouldn't count on it.
2)
Typically, when you delete a child with two nodes, you promote the left or right node to the position the deleted node was in. (This is a highly simplistic case, I'm assuming your tree isn't balanced)
2.b)
Your delete code has some problems. I'd recommend walking through it with a few hypothetical situations. Immediately obvious to me was free'ing a pointer and then deferencing it:
free(cliPtr);
cliPtr->clientProfile = NULL;
Of course, you can always worry about style once you get the correctness thing squared away.
Ideally there are three cases for deletion of a node in BST:
Case 1:
X has no children: remove X
Case 2:
X has one children : Splice out X
Case 3:
X has two children : swap X with its successor and follow case #1 or #2
So for the missing delete case:
When X (node to delete) has two children, replace X with the successor of X and follow case #1 or case #2. You can also replace with its predecessor, might be a good alternative.
if ( X->left && X->right)
{
NODE *Successor = FindSuccessor(X);
X->data = Successor->data;
free(Successor);
}
this binary codes are insert, delete,search, and quit.
Examples:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Binary Tree {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
LinkedList ll = new LinkedList();
ll.add("\n"+"mai 0020");
ll.add("\n"+"king 0019");
ll.add("\n"+"maan 0002");
ll.add("\n"+"dimple 0024");
ll.add("\n"+"eman 0004");
ll.add("\n"+"lara 0005");
ll.add("\n"+"cute 0008");
ll.add("\n"+"irene 0011");
ll.add("\n"+"sheena 0030");
ll.add("\n"+"aisy 0003");
System.out.println("display: " + ll);
System.out.println("\n\n");
for(int c=0; c<=10; c++) {
System.out.println("select from: 1-insert, 2-delete," +
" 3-display, 4-search, 5-quit");
String x = br.readLine();
int y = Integer.parseInt(x);
switch (y) {
case 1: //inserting
System.out.println("input name");
String n= br.readLine();
System.out.println("input a list number");
String o = br.readLine();
int z = Integer.parseInt(o);
ll.add("\n"+n+" "+z);
break;
case 2: // delete
ll.removeFirst();
break;
case 3: //Display
System.out.println("\n\n"+"List of employee: " + ll);
System.out.println("\n\n");
break;
case 4: //search
System.out.println("\n");
System.out.println("Search");
System.out.println("first element of the Linkedlist is: "
+ ll.getFirst());
System.out.println("\n\n");
System.out.println("last element of linkedlist:"
+ ll.getLast());
break;
case 5: //quit
System.out.println("\n\n\n\n\n"
+ " Thank You Very Much!!!!!!!\n\n\n");
System.exit(0);
break;
}
}
}
}
int delete_value(Tree*&root,Tree*&find,Tree*&ptr,int numb){
if(find->value==number){
//the number exist in the root,so we should find the highest value inside the right brache and replace it with the root.
Tree*ptr2=NULL;
Tree*ptr3=NULL;//pointer pointing to the parent of the last element of ptr2.
ptr2=root->right;
while(ptr2!=NULL){
ptr3=ptr2;
ptr2=ptr2->left;
}
if(ptr2->right!=NULL){
ptr3->left=ptr2->right;
}
swap(ptr2->value,root->value);
delete ptr2;
ptr2=ptr3=NULL;
}
else{
while(find->value!=numb){
if(find->value!=numb){
ptr=find;
}
if(find->value < numb){
find=find->right;
return delete_value(root,find,ptr,numb);
}
else{
find=find->left;
return delete_value(root,find,ptr,numb);
}
}//end of while
}//end of else
//the pointer find is pointing at the element we want to delete.
//the pointer ptr is pointing at the element before the one's we want to delete.
//case 1:the element to delete don't have any children
if(find->right==NULL && find->left==NULL){
if(ptr->left=find){
ptr->left=NULl;
delete find;
}
else{
ptr->right=NULL;
delete find;
}
}//end of the first case.
//case 2:the element has one child it could be to the left or to the right.
//a-child to the right.
if( find->right!=NULL && find->left==NULL ){
Tree*ptr2=find->right;
while(ptr2!=NULL){
ptr2=ptr2->left;//find the highest value in the right branche and replace it with the delete element
}
swap(find->value,ptr2->value);
delete ptr2;
ptr2=NULL;
}
//b-child to the left.
if(find->right==NULL && find->left!=NULL){
Tree*ptr2=find->left;
//check wether the find element is to the right or to the left of ptr.
if(ptr->left==find){
ptr->left=ptr2;
delete find;
}
else{
ptr->right=ptr2;
delete find;
}
}//end of the second case.
//case3: the element has to children.
if(find->right!=NULL&&find->left!=NULL){
Tree*ptr2=find->left;
while(ptr2->right!=NULL){
ptr2=ptr2->right;
}
swap(ptr2->value,find->value);
delete ptr2;
ptr2=NULL;
}//end of case 3.
}//end of the function.