#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char line[100]; /* buffer for input data */
int n; /* control for loop */
struct node {
char *data; /* word for this tree */
struct node *left; /* tree to the left */
struct node *right; /* tree to the right */
};
struct node *root = NULL;
char *saveString();
void enter();
void scan();
void printTree();
struct node *findTree();
void deleteTree();
int deepChild();
struct node *percolateDown();
struct node *searchParent();
void complexDelete();
void complexDeleteR();
struct node *searchParentL();
int main(int argc, char *argv[]) {
struct node *cur_node; /* node to delete */
printf("Enter file name\n");
fgets(line, sizeof(line), stdin);
line[strlen(line) - 1] = '\0';
scan(line);
printTree(root);
printf("Enter word to delete\n");
fgets(line, sizeof(line), stdin);
line[strlen(line) - 1] = '\0';
cur_node = root;
cur_node = findTree(cur_node, line);
if (cur_node == NULL ) {
printf("Don't find word");
} else {
printf("Find! word\n");
printTree(root);
deleteTree(cur_node, root);
printTree(root);
}
return 0;
}
char *saveString(char *st) {
char *newst; /* char array for copy */
newst = malloc((unsigned) (strlen(st) + 1));
if (newst == NULL ) {
fprintf(stderr,"out of memory\n");
exit(8);
}
strcpy(newst, st);
return newst;
}
void enter(struct node **node, char *st) {
int res; /* result of compare data with st */
if ((*node) == NULL ) {
(*node) = malloc(sizeof(struct node));
if ((*node) == NULL ) {
fprintf(stderr,"out of memory\n");
exit(8);
}
(*node)->data = saveString(st);
(*node)->left = NULL;
(*node)->right = NULL;
}
res = strcmp((*node)->data, st);
/* if already contain word return */
if (res == 0) {
return;
} else if (res < 0) {
enter(&(*node)->right, st);
} else {
enter(&(*node)->left, st);
}
}
void scan(char *li) {
char word[100]; /* char array for each word */
int ch; /* temporary char and used int for EOF */
FILE *in_file; /* file from user */
in_file = fopen(li, "r");
if (in_file == NULL ) {
fprintf(stderr,"unable to open file %s\n",li);
exit(8);
}
while (1) {
while (1) {
ch = fgetc(in_file);
if (ch != ' ' || ch == EOF)
break;
}
if (ch == EOF)
break;
word[0] = ch;
for (n = 1; n < 100; ++n) {
ch = fgetc(in_file);
if (ch == ' ' || ch == EOF)
break;
word[n] = ch;
}
word[n] = '\0';
enter(&root, word);
}
fclose(in_file);
}
void printTree(struct node *top) {
if (top == NULL )
return;
printTree(top->left);
printf("%s ", top->data);
printTree(top->right);
}
struct node *findTree(struct node *cur, char *w) {
int resu = 1;
if (cur != NULL ) {
resu = strcmp(cur->data, w);
if (resu < 0) {
return findTree(cur->right, w);
} else if (resu > 0) {
return findTree(cur->left, w);
} else {
return cur;
}
} else {
return NULL ;
}
}
void deleteTree(struct node *cur, struct node *sroot) {
struct node *childl = NULL;
struct node *childr = NULL;
struct node *parent = NULL;
printf("%s %s\n", cur->data, sroot->data);
if (strcmp(sroot->data, cur->data) == 0) {
if (sroot->left != NULL )
childl = sroot->left;
if (sroot->right != NULL )
childr = sroot->right;
if (childl == NULL && childr == NULL ) {/* if block 1 */
parent = searchParentL(sroot,root);
if(parent->left==sroot)
parent->left = NULL;
if(parent->right==sroot)
parent->right = NULL;
free(sroot);
sroot = NULL;
} else if (childl == NULL ) {
if(childr->left == NULL&&childr->right == NULL){
sroot->data = childr->data;
free(childr);
sroot->right = NULL;
}else{
complexDeleteR(childr,sroot);
}
} else if (childr == NULL ) {
sroot->data = childl->data;
if(childl->left==NULL&&childl->right==NULL)
sroot->left = NULL;
if(childl->left!=NULL){
sroot->left = childl->left;
}
if(childl->right!=NULL){
sroot->right = childl->right;
if(childl->left==NULL)
sroot->left = NULL;
}
free(childl);
} else {/* block 1 childl&childr != NULL*/
if (childl->left != NULL && childl->right != NULL ) {/* if block 2 */
if (childr->left == NULL && childr->right == NULL ) {
sroot->data = childr->data;
sroot->right = NULL;
free(childr);
childr = NULL;
} else if (childr->left == NULL ) {
sroot->data = childr->data;
sroot->right = childr->right;
free(childr);
childr = NULL;
} else if (childr->right == NULL ) {
sroot->data = childr->data;
sroot->right = childr->left;
free(childr);
childr = NULL;
}
} else if (childl->left == NULL && childl->right == NULL ) {
sroot->data = childl->data;
sroot->left = NULL;
free(childl);
childl = NULL;
} else if (childl->left == NULL ) {
if(childl->right->left == NULL&&childl->right->right == NULL){
sroot->data = childl->right->data;
free(childl->right);
childl->right = NULL;
}else{
complexDelete(childl,sroot);
}
} else if (childl->right == NULL ) {
sroot->data = childl->data;
sroot->left = childl->left;
free(childl);
childl = NULL;
} else {/* childl & childr full *//* block 2 */
complexDelete(childl,sroot);
}/* end if block 2 */
}/* end if block 1 */
} else if (strcmp(sroot->data, cur->data) > 0) {
deleteTree(cur, sroot->left);
} else if (strcmp(sroot->data, cur->data) < 0) {
deleteTree(cur, sroot->right);
}
}
int deepChild(struct node *cur) {
struct node *childl = NULL;
struct node *childr = NULL;
int deepcount = 0;
int leftcount = 0;
int rightcount = 0;
if (cur->left != NULL )
childl = cur->left;
if (cur->right != NULL )
childr = cur->right;
if (childl == NULL && childr == NULL ) {
return 0;
} else {
if (childl != NULL || childr != NULL )
++deepcount;
if (childl != NULL )
leftcount = deepChild(childl);
if (childr != NULL )
rightcount = deepChild(childr);
if (leftcount >= rightcount)
deepcount += leftcount;
else
deepcount += rightcount;
return deepcount;
}
}
struct node *percolateDown(struct node *cur) {
struct node *childr = NULL;
if (cur->right != NULL )
childr = cur->right;
if (childr == NULL ) {
return cur;
} else {
return (percolateDown(childr));
}
}
struct node *searchParent(struct node *cur, struct node *ssroot) {
struct node *childr = NULL;
if (ssroot->right != NULL )
childr = ssroot->right;
if (childr == cur) {
return ssroot;
} else {
return (searchParent(cur, childr));
}
}
void complexDelete(struct node *childl, struct node *sroot) {
struct node *pchild = NULL;
struct node *schild = NULL;
struct node *pchildl = NULL;
int deepl = 0;
int deepr = 0;
/*deepl = deepChild(childl);
deepr = deepChild(childr);
if(deepl>=deepr)
pchild = percolateDown(childr);
else*/
pchild = percolateDown(childl);
schild = searchParent(pchild, childl);
if (pchild->left != NULL ) {/* if block 3 */
pchildl = pchild->left;
if (schild != childl) {
sroot->data = pchild->data;
schild->right = pchildl;
free(pchild);
pchild = NULL;
} else {/* schild == childl */
sroot->data = pchild->data;
childl->right = pchildl;
free(pchild);
pchild = NULL;
}
} else {/* block 3 pchild->left == NULL*/
if (schild != childl) {
sroot->data = pchild->data;
schild->right = NULL;
free(pchild);
pchild = NULL;
} else {/* schild == childl */
sroot->data = pchild->data;
childl->right = NULL;
free(pchild);
pchild = NULL;
}
}/* end if block 3 */
}
void complexDeleteR(struct node *childr, struct node *sroot){
struct node *pchild = NULL;
struct node *pchildl = NULL;
struct node *schild = NULL;
pchild = percolateDown(childr);
if(pchild==childr){
if (pchild->left != NULL ) {/* if block 3 */
pchildl = pchild->left;
sroot->data = pchild->data;
sroot->left = pchildl;
sroot->right = NULL;
free(pchild);
pchild = NULL;
} else {/* block 3 pchild->left == NULL*/
sroot->data = pchild->data;
sroot->right = NULL;
free(pchild);
pchild = NULL;
}/* end if block 3 */
}else{
schild = searchParentL(sroot,root);
schild->left = childr;
free(sroot);
sroot = NULL;
}
}
struct node *searchParentL(struct node *cur, struct node *sroot){
struct node *childl = NULL;
struct node *childr = NULL;
int res =1;
if(sroot->left!=NULL)
childl = sroot->left;
if(sroot->right!=NULL)
childr = sroot->right;
res = strcmp(sroot->data,cur->data);
if(res<0){
res = strcmp(childr->data,cur->data);
if(res==0){
return sroot;
}else{
return searchParentL(cur,childr);
}
}else if(res>0){
res = strcmp(childl->data,cur->data);
if(res==0){
return sroot;
}else{
return searchParentL(cur,childl);
}
}
}
คือ ผมเอง ลองไปแค่ file เดียวเอง ยังไม่ค่อย แน่ใจ เท่าไหร่
แต่ ที่รู้คือ tree นี่ยาก กว่า linked_list และ double linked_list เยอะ มาก ๆ











