Thread: Help with insert/delete binary search tree

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Mar 2006
    Posts
    158
    You're right... Actually, what I mean was that I wasn't using recursion in the sense of returning a value, instead, I pass the address of structure as an argument. I misunderstood what I wanted to say...

    Someone else suggested me to use iteration over recursion because of possible stack problems. But I have no clue on how could I do a delete function of a binary search tree, or even just a "print-all-nodes-and-childs" functions without using recursion. I can do that with a linked-list, I just need to use "while" one time, but for a binary search tree with 2 childs? How do I do that? Also, the same person said something about freeing a pointer and then deferencing it:
    Code:
    free(cliPtr);
    
    cliPtr->clientProfile = NULL;
    Is there anything wrong with this?
    Last edited by Nazgulled; 03-24-2009 at 07:30 AM.

  2. #2
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by Nazgulled View Post
    Someone else suggested me to use iteration over recursion because of possible stack problems. But I have no clue on how could I do a delete function of a binary search tree, or even just a "print-all-nodes-and-childs" functions without using recursion. I can do that with a linked-list, I just need to use "while" one time, but for a binary search tree with 2 childs? How do I do that? Also, the same person said something about freeing a pointer and then deferencing it:
    Code:
    free(cliPtr);
    
    cliPtr->clientProfile = NULL;
    Is there anything wrong with this?
    Hadn't looked close enough to notice that. Yeah that's a bad thing to do. If you're lucky it might work a few times, but then it'll go boom sooner or later. You must not access or write to a structure after it has been freed.
    In this case you can just delete this line:
    Code:
    cliPtr->clientProfile = NULL;
    There's no point setting something to NULL when it's going out of existence.

    Converting tail-recursion into iteration is not particularly hard. However if the function makes two recursive calls then only one of them can be turned into iteration.

    I'll illustrate how one can make a tree node counting function semi-iterative.
    Double Recursion:
    Code:
    // Returns the number of items in the tree
    int TreeCount(const TItem *head) {
    	int count = 0;
    	if (head != NULL) {
    		//recursively count left nodes (add one for this node)
    		count += TreeCount(head->left) + 1;
    		//recursively count right nodes
    		count += TreeCount(head->right);
    	}
    	return count;
    }
    Semi Iterative / Semi Recursive:
    Code:
    // Returns the number of items in the tree
    int TreeCount(const TItem *head) {
    	int count = 0;
    	while (head != NULL) {
    		//recursively count left nodes (add one for this node)
    		count += TreeCount(head->left) + 1;
    		//iteratively count right nodes
    		head = head->right;
    	}
    	return count;
    }
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  3. #3
    Registered User
    Join Date
    Mar 2006
    Posts
    158
    Quote Originally Posted by iMalc View Post
    Hadn't looked close enough to notice that. Yeah that's a bad thing to do. If you're lucky it might work a few times, but then it'll go boom sooner or later. You must not access or write to a structure after it has been freed.
    In this case you can just delete this line:
    Code:
    cliPtr->clientProfile = NULL;
    There's no point setting something to NULL when it's going out of existence.
    Hum... When I use free on something and if in the next line I try to print it's value anyways, the value will still be there, that's why I set the variable to NULL. To make sure it's cleaned.

    I guess free cleans that memory block and the data will still be there until something else overwrites it and it's the day it's supposed to work, right?

    Hum... After searching a bit for iteration on binary trees I found an algorithm for iterative insert, here's what I did:

    Code:
    void addClientToTree(ClientTree *cTree, ClientProfile cProfile) {
    	if(!*cTree) {		
    		*cTree = newClientTreeNode(cProfile);
    		return;
    	}
    	
    	ClientTree currPtr = *cTree;
    	int nCompare;
    	
    	do {
    		nCompare = strcmp(currPtr->clientName, cProfile->clientName);
    			
    		if(nCompare > 0) {
    			if(!currPtr->leftTree) {
    				currPtr->leftTree = newClientTreeNode(cProfile);
    				return;
    			} else {
    				currPtr = currPtr->leftTree;
    			}
    		} else if(nCompare < 0) {
    			if(!currPtr->rightTree) {
    				currPtr->rightTree = newClientTreeNode(cProfile);
    				return;
    			} else {
    				currPtr = currPtr->rightTree;
    			}
    		}
    	} while(currPtr && nCompare != 0);
    	
    	return;
    }
    Code:
    ClientTree newClientTreeNode(ClientProfile cProfile) {
    	ClientTree newClient = malloc(sizeof(nClientTree));
    	
    	if(!newClient) perror("malloc");
    		
    	newClient->clientName = strdup(cProfile->clientName);
    	
    	if(!newClient->clientName) perror("strdup");
    	
    	newClient->clientProfile = cProfile;
    	
    	newClient->leftTree = NULL;
    	newClient->rightTree = NULL;
    	
    	return newClient;
    }
    I guess it's ok now?

    I'll try to convert my delete function into iteration and see if I can also delete a nod with 2 child's...

  4. #4
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by Nazgulled View Post
    Hum... When I use free on something and if in the next line I try to print it's value anyways, the value will still be there,
    How do you know it?
    memory does not belongs to your program - it is returned to the memory pool...

    if this free just returned the last chunk of the memory in some page - the whole page could be already returned to the OS making any address inside this page not available to the program at all.

    So even read operation from this address could cause a GPF
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. BST (Binary search tree)
    By praethorian in forum C++ Programming
    Replies: 3
    Last Post: 11-13-2005, 09:11 AM
  2. Binary Tree Search
    By nickname_changed in forum C++ Programming
    Replies: 7
    Last Post: 01-13-2004, 12:40 AM
  3. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  4. Binary Search Tree, Inserting node
    By cheryl_li in forum C Programming
    Replies: 1
    Last Post: 09-13-2003, 03:53 AM
  5. BST/Red and Black Tree
    By ghettoman in forum C++ Programming
    Replies: 0
    Last Post: 10-24-2001, 10:45 PM

Tags for this Thread