
/*	tree-demo.c

	Driver for a binary search tree container implementation.

	by: Steven Skiena
	begun: September 5, 2005
*/


/*
Copyright 2005 by Steven S. Skiena; all rights reserved. 

Permission is granted for use in non-commerical applications
provided this copyright notice remains intact and unchanged.

This program appears in my book:

"Programming Challenges: The Programming Contest Training Manual"
by Steven Skiena and Miguel Revilla, Springer-Verlag, New York 2003.

See our website www.programming-challenges.com for additional information.

This book can be ordered from Amazon.com at

http://www.amazon.com/exec/obidos/ASIN/0387001638/thealgorithmrepo/

*/


#include "tree.h"
#include <stdio.h>
#include "bool.h"

tree *parent;				/* last node visited */

tree *init_tree()
{
        return(NULL);
}

bool empty_tree(tree *t)
{
        if (t == NULL) return (TRUE);
        else return (FALSE);
}

tree *search_tree(tree *l, int x)
{
	if (l == NULL) return(NULL);

	if (l->item == x) return(l);

	if (x < l->item)
		return( search_tree(l->left, x) );
	else
		return( search_tree(l->right, x) );
}


void insert_tree(tree **l, int x, tree *parent)
{
	tree *p;			/* temporary pointer */

	if (*l == NULL) {
		p = malloc( sizeof(tree) );
		p->item = x;
		p->left = p->right = NULL;
		p->parent = parent;
		*l = p;
		return;
	}

	if (x < (*l)->item)
		insert_tree(&((*l)->left), x, *l);
	else
		insert_tree(&((*l)->right), x, *l);
}


print_tree(tree *l)
{
        if (l != NULL) {
		print_tree(l->left);
                printf("%d ",l->item);
		print_tree(l->right);
	}

}

tree *delete_tree(tree *t, int x)
{
	tree *d;			/* node with key to delete */
	tree *p;			/* node to be physically deleted */
	tree *troot;			/* pointer to root of tree */
	tree *search_tree();

	d = search_tree(*t,x);

	if (d == NULL) {
		printf("Warning: key to be deleted %d is not in tree.\n",x);
		return(t);
	}

        if ((t->left == NULL) && (t->right == NULL))
                troot = NULL;
        else
                troot = t;		/* identify root of returned tree */


	if (d->left != NULL) {		/* copy rightmost left decendant over d */
		p = d->left;
		while (p->right != NULL) 
			p = p->right;
		d->item = p->item;
		(p->parent)->right = p->left;
	}
	else if (d->right != NULL) {	/* copy leftmost right decendant over d */
		p = d->right;
		while (p->left != NULL)
			p = p->left;
		d->item = p->item;
		(p->parent)->left = p->right;
	}
	else {				/* leaf deletion */
		if (d->parent != NULL) {
			if ((d->parent)->left == d)
				(d->parent)->left == NULL;
			else
				(d->parent)->right == NULL;
		}
		p = d;
	}

	free(p);
	return(troot);
}


main()
{
	char c;			/* input character */
	int d;			/* input item */
	tree *l;		/* tree under construction */
	tree *tmp;		/* returned tree from search */
	tree *search_tree();
	void insert_tree();

	l = init_tree();

	while (scanf("%c",&c) != EOF) {
		if (tolower(c) == 'p') {
			print_tree(l);
			printf("\n");
		}
		if (tolower(c) == 'i') {
			scanf("%d",&d);
			printf("new item: %d\n",d);
			insert_tree(&l,d, NULL);
		}
		if (tolower(c) == 's') {
			scanf("%d",&d);
			tmp = search_tree(l,d);
			if (tmp == NULL) 
				printf("item %d not found\n",d);
			else
				printf("item %d found\n",d);
		}
		if (tolower(c) == 'd') {
			scanf("%d",&d);
                        l = delete_tree(l,d);
                        if (l == NULL)
                                printf("item to delete %d not found\n",d);
			else
				printf("item %d deleted\n",d);
		}
	}
}


