binaryDigit
05-05-2001, 09:36 PM
i've been working on this for about a week. i can't seem to write anything that works. so i'm asking for help.
i can't get the functions that delete a node in the tree to work. the problem is either i seg fault or the program hangs because it starts to look for something that doesn't exist anymore.
i need to be able to delete a node on the tree without completely destroying the search path to the rest of the nodes in the tree. as long as the rest of the nodes stay generally in the search path the program will work. i just can't seem to get it done.
i know the code is sloppy and the variable names suck, but i'm just sick of dealing with this.
please help me......... please.
#include <stdio.h>
#include <stdlib.h>
typedef struct _node { struct _node *l, *r; int k; }_node;
typedef struct _search { _node *p, *c; }_search;
int add_node(_node *, int);
void put_node(_node *, _node *, int);
_search find_node(_node *, int);
int del_node(_node *, int);
void kill_node(_node **);
int
add_node(_node *root, int key) {
_node *new;
if(root == NULL) return 0; /* root should already be allocated */
if(find_node(root, key).c != NULL) return 0; /* duplicate item */
/* allocate space and check for failure of malloc */
if((new = (struct _node *) malloc(sizeof(_node))) == NULL) exit(EXIT_FAILURE);
/* set defaults */
new -> l = NULL; new -> r = NULL; new -> k = key;
/* find a place for new space */
put_node(root, new, 1);
/* a bit of an assumption */
return 1;
} /* end of add_node() */
void
put_node(_node *root, _node *new, int level) {
/* first check the path for the new key */
/*
* first block we go to the right. when we find
* a place for the new item we stop
*/
if((new -> k & level) == level) {
if(root -> r == NULL) root -> r = new;
else { level <<= 1; put_node(root -> r, new, level); }
}
/* path is to the left */
else {
if(root -> l == NULL) root -> l = new;
else { level <<= 1; put_node(root -> l, new, level); }
}
} /* end of put_node() */
_search
find_node(_node *root, int key) {
_search locate;
int level = 1;
/* set up initial search pair */
locate.p = NULL;
locate.c = root;
/* nothing to look for */
if(locate.c == NULL) return locate;
while(locate.c != NULL) {
/* found the item. */
if(locate.c -> k == key) break;
/* search right */
else if((key & level) == level) {
locate.p = locate.c;
locate.c = locate.c -> r;
level <<= 1;
}
/* search left */
else {
locate.p = locate.c;
locate.c = locate.c -> l;
level <<= 1;
}
}
return locate;
} /* end of find() */
int
del_node(_node *root, int key) {
_search locate;
locate = find_node(root, key);
/* item wasn't found or nothing to delete */
if(locate.c == NULL) return 0;
/* node to kill is root node */
if(locate.p == NULL) { kill_node(&root); return 1; }
/* node to kill is left child of parent node */
else if(locate.p -> l == locate.c) {
kill_node(&locate.p -> l);
return 1;
}
/* node to kill is right child of parent node */
else {
kill_node(&locate.p -> r);
return 1;
}
} /* end of del_node */
/* ------------------------*
* this is where i'm stuck *
* *
*-------------------------*/
void
kill_node(_node **n) {
_node *tmp;
if((*n) -> l == NULL) {
tmp = *n;
*n = (*n) -> r;
free(tmp);
}
else if((*n) -> r == NULL) {
tmp = *n;
*n = (*n) -> l;
free(tmp);
}
else {
tmp = (*n) -> l;
while((tmp -> l != NULL) || (tmp -> r != NULL)) {
if(tmp -> l != NULL) tmp = tmp -> l;
else if(tmp -> r != NULL) tmp = tmp -> r;
else break;
}
tmp -> r = (*n) -> r;
tmp -> l = (*n) -> l;
tmp = *n;
free(tmp);
}
tmp = NULL;
} /* end of kill_node() */
int
main(void) {
int i = 0, max = 100, size = 0;
_node *root;
root = (struct _node *) malloc(sizeof(_node));
root -> r = NULL; root -> l = NULL; root -> k = -1;
size = 1;
for(i = 0; i < max; i++) {
if(add_node(root, i) == 0) printf("\nfailed add of %d\n", i);
else size++;
}
printf("\nsize = %d after add loop\n", size);
for(i = 0; i < max; i++) {
if(del_node(root, i) == 0) printf("\nfailed delete of %d\n", i);
else size--;
}
printf("\nsize = %d before delete of root\n", size);
free(root);
size--;
printf("\nsize = %d after delete of root\n", size);
return 0;
}
i can't get the functions that delete a node in the tree to work. the problem is either i seg fault or the program hangs because it starts to look for something that doesn't exist anymore.
i need to be able to delete a node on the tree without completely destroying the search path to the rest of the nodes in the tree. as long as the rest of the nodes stay generally in the search path the program will work. i just can't seem to get it done.
i know the code is sloppy and the variable names suck, but i'm just sick of dealing with this.
please help me......... please.
#include <stdio.h>
#include <stdlib.h>
typedef struct _node { struct _node *l, *r; int k; }_node;
typedef struct _search { _node *p, *c; }_search;
int add_node(_node *, int);
void put_node(_node *, _node *, int);
_search find_node(_node *, int);
int del_node(_node *, int);
void kill_node(_node **);
int
add_node(_node *root, int key) {
_node *new;
if(root == NULL) return 0; /* root should already be allocated */
if(find_node(root, key).c != NULL) return 0; /* duplicate item */
/* allocate space and check for failure of malloc */
if((new = (struct _node *) malloc(sizeof(_node))) == NULL) exit(EXIT_FAILURE);
/* set defaults */
new -> l = NULL; new -> r = NULL; new -> k = key;
/* find a place for new space */
put_node(root, new, 1);
/* a bit of an assumption */
return 1;
} /* end of add_node() */
void
put_node(_node *root, _node *new, int level) {
/* first check the path for the new key */
/*
* first block we go to the right. when we find
* a place for the new item we stop
*/
if((new -> k & level) == level) {
if(root -> r == NULL) root -> r = new;
else { level <<= 1; put_node(root -> r, new, level); }
}
/* path is to the left */
else {
if(root -> l == NULL) root -> l = new;
else { level <<= 1; put_node(root -> l, new, level); }
}
} /* end of put_node() */
_search
find_node(_node *root, int key) {
_search locate;
int level = 1;
/* set up initial search pair */
locate.p = NULL;
locate.c = root;
/* nothing to look for */
if(locate.c == NULL) return locate;
while(locate.c != NULL) {
/* found the item. */
if(locate.c -> k == key) break;
/* search right */
else if((key & level) == level) {
locate.p = locate.c;
locate.c = locate.c -> r;
level <<= 1;
}
/* search left */
else {
locate.p = locate.c;
locate.c = locate.c -> l;
level <<= 1;
}
}
return locate;
} /* end of find() */
int
del_node(_node *root, int key) {
_search locate;
locate = find_node(root, key);
/* item wasn't found or nothing to delete */
if(locate.c == NULL) return 0;
/* node to kill is root node */
if(locate.p == NULL) { kill_node(&root); return 1; }
/* node to kill is left child of parent node */
else if(locate.p -> l == locate.c) {
kill_node(&locate.p -> l);
return 1;
}
/* node to kill is right child of parent node */
else {
kill_node(&locate.p -> r);
return 1;
}
} /* end of del_node */
/* ------------------------*
* this is where i'm stuck *
* *
*-------------------------*/
void
kill_node(_node **n) {
_node *tmp;
if((*n) -> l == NULL) {
tmp = *n;
*n = (*n) -> r;
free(tmp);
}
else if((*n) -> r == NULL) {
tmp = *n;
*n = (*n) -> l;
free(tmp);
}
else {
tmp = (*n) -> l;
while((tmp -> l != NULL) || (tmp -> r != NULL)) {
if(tmp -> l != NULL) tmp = tmp -> l;
else if(tmp -> r != NULL) tmp = tmp -> r;
else break;
}
tmp -> r = (*n) -> r;
tmp -> l = (*n) -> l;
tmp = *n;
free(tmp);
}
tmp = NULL;
} /* end of kill_node() */
int
main(void) {
int i = 0, max = 100, size = 0;
_node *root;
root = (struct _node *) malloc(sizeof(_node));
root -> r = NULL; root -> l = NULL; root -> k = -1;
size = 1;
for(i = 0; i < max; i++) {
if(add_node(root, i) == 0) printf("\nfailed add of %d\n", i);
else size++;
}
printf("\nsize = %d after add loop\n", size);
for(i = 0; i < max; i++) {
if(del_node(root, i) == 0) printf("\nfailed delete of %d\n", i);
else size--;
}
printf("\nsize = %d before delete of root\n", size);
free(root);
size--;
printf("\nsize = %d after delete of root\n", size);
return 0;
}