|
||||
Title: CS: Binary Tree Print Post by Jonathan the Red on Aug 1st, 2002, 1:20pm Quote:
Well, the below works... Code:
...but it takes O(n log n) to complete. Can it be done more efficiently? |
||||
Title: Re: CS: Binary Tree Print Post by Jonathan the Red on Aug 1st, 2002, 1:25pm I'm a gimboid... change the lines that look like this: Code:
...to this. Damned short-circuiting... Code:
|
||||
Title: Re: CS: Binary Tree Print Post by -D- on Aug 1st, 2002, 1:30pm To print out level by level I would use a breadth first search. Running time is O(|V|+|E|) which is some kind of linear. You need a queue of pointers to nodes of the tree. Basic algorithm PrintTree() { enqueue( head ) while( p = dequeue() ) { print_element_at( p ); enqueue( p.left ); enqueue( p.right ); } } |
||||
Title: Re: CS: Binary Tree Print Post by -D- on Aug 1st, 2002, 1:37pm I'm a dork. O(|V|+|E|) is for graphs, this is a tree, it should just be O(n). Although a binary tree can be considered a special form of graph. -D- |
||||
Title: Re: CS: Binary Tree Print Post by srowen on Aug 1st, 2002, 5:19pm Yeah, breadth-first traversal using the queue is the elegant way... faster than repeatedly depth-first-searching the tree, deeper each time. If you substitute "push" for "enqueue" and "pop" for "dequeue" (i.e., use a stack instead of a queue) into this same basic algorithm you get depth-first search. First time I saw that I thought that was a great insight. |
||||
Title: Re: CS: Binary Tree Print Post by -D- on Aug 1st, 2002, 10:37pm How would push/pop be able to replace enqueue/dequeue? 1 / \ 2 3 / \ / \ 4 56 7 push 1 pop 1 push 2 push 3 pop 3 push 6 push 7 pop 7 <-- error I'm assuming i made a mistake in my thinking... -D- |
||||
Title: Re: CS: Binary Tree Print Post by -D- on Aug 1st, 2002, 10:42pm I'm a dork again... I thought you said it would do the same thing. You're right, it'll do a depth first search. However if you're going to do a depth first search, you might as well just use recursion, it's just about as costly and you don't have to use a stack. PrintTreeDepthFirst() { PrintNode( head ); } PrintNode( node *p ) { printElement( p ); PrintNode( p->left ); PrintNode( p->right ); } ... vs ... PrintTreeDepthFirst() { push( head ) while( p = pop() ) { printElement( p ); push( p->left ); push( p->right ); } } Neither way is any better I suppose.... I think I'd rather use recursion instead of set up a stack, and I -HATE- STL. -D- |
||||
Title: Re: CS: Binary Tree Print Post by S. Owen on Aug 7th, 2002, 9:55am on 08/01/02 at 22:42:20, -D- wrote:
And for our viewers - note that a recursive solution is using a stack too, but implicitly - the function call stack. Agreed that it's easier to not have to code that though. |
||||
Title: Re: CS: Binary Tree Print Post by Nyarly on Aug 23rd, 2002, 1:34pm on 08/07/02 at 09:55:37, S. Owen wrote:
Easier to code, if you don't a stack implementation already. Harder to understand for any but a real hacker, and hardly more efficient. The call stack is almost always bigger than an a generic stack (what with return information and all), and you take the function call hit with every iteration. And besides, when you debug it, your call stack is going to grow and grow and... Of course, maybe that's better than you stack implementation indenting off the map... OT - Why doesn't any debugger understand the idea of a linked list? Sometimes they do arrays nicely, (Codewarrior and gdb, but not MS's sludge) but I've yet to see a debugger not indent a linked list into oblivion (and Ritchee help you if you're looking a graph). >:( |
||||
Title: Re: CS: Binary Tree Print Post by moonz on Jul 24th, 2003, 12:43am Another implementation without using the Node Levels instead. ;) prev mens "Left" and next means "Right" .. int BinaryTree::findTreedepth(Node* node) { if (!node) return 0; int x = findTreedepth(node->prev); int y = findTreedepth(node->next); return (x>y) ? 1+x:1+y; } void BinaryTree::printNodeLevelWise(Node *node,int printLevel, int depth) { if (!node) return; depth++; if (printLevel == depth) printf("Node at Level %d is: %d\n",printLevel,node->val); else printNodeLevelWise(node->prev, printLevel, depth); printNodeLevelWise(node->next, printLevel, depth); } void BinaryTree::printTreeLevelWise() { int depth = findTreedepth(root); if (!depth) return; for (int i = 1 ; i <= depth ; i++) { printNodeLevelWise(root,i,0); } } |
||||
Title: Re: CS: Binary Tree Print Post by James Fingas on Jul 30th, 2003, 2:04pm Here's another way: Find the height of the tree, then convert the tree into a heap-like tree (in an array), indicating which elements are null. Caveat: this takes time O( exp(height of tree) ), bad for a poorly balanced tree. Now print out the heap-tree, ignoring empty spots. |
||||
Title: Re: CS: Binary Tree Print Post by Johan on Jan 24th, 2007, 5:28am on 08/01/02 at 13:20:21, Jonathan the Red wrote:
It is actually O(n), not O(n log n). And it's much more memory effiecient than the queuing solutions (O(n)). But only if the tree is balanced. (For a totally unbalanced tree (with just one leg) its is O(n²) and uses O(n) memory (for the return stack).) Why is it O(n) and not O(N log n)? For level one: 1 node is checked. For level two: 1+2 nodes For level three: 1+2+4 nodes ... For level log(N): 1+2+...+N/2 As you can see every new level uses more than twice the time of the previous level, and consequently more time than all the lower levels taken together! (I leave the formal proof to someone less rusty.) Thus the final level takes more than half the total time. The final level takes only O(n) time (visiting every node once). Thus the total time is less than 2*O(n) which is of course O(n) OK, not a very neat proof.... But it's been a long time. :P Comments? Anyone can do it nicer? |
||||
Powered by YaBB 1 Gold - SP 1.4! Forum software copyright © 2000-2004 Yet another Bulletin Board |