|
CS 2213/2211 Advanced Programming Spring 2005 Recitation 12: Binary Trees Week 12: Apr 12-14 Due (on time): 2005-04-19 23:59:59 Due (late): 2005-04-24 23:59:59 |
Recitation 12 should be submitted
following directions at: submissions with deadlines
|
Binary search tree, inserting single chars | ||
---|---|---|
tree.c | tree.h, treetest.h | |
/* tree.c: create binary tree */ #include <stdio.h> #include <ctype.h> #include <string.h> #include <stdlib.h> #include "tree.h" struct tnode { char ch; struct tnode *left; struct tnode *right; }; static struct tnode *newnode(char ); static void treeprint2(struct tnode *); struct tnode *root = NULL; /* insert: add a node, non-recursive */ void insert(char c) { struct tnode *p; if (root == NULL) { /* empty tree */ root = newnode(c); return; } p = root; for (;;) { if ((p -> ch) == c) return;/*dups */ else if ((p -> ch) > c) { /* left */ if ((p -> left) == NULL) { p -> left = newnode(c); return; } else p = p -> left; } else if ((p -> ch) < c) {/* right */ if ((p -> right) == NULL) { p -> right = newnode(c); return; } else p = p -> right; } } } |
/* newnode: fix up a new node */ static struct tnode *newnode(char c) { struct tnode *p = (struct tnode *) malloc(sizeof(struct tnode)); p -> ch = c; p -> left = p -> right = NULL; return p; } /* treeprint: recursive inorder print */ void treeprint(void) { treeprint2(root); } /* treeprint2: recursive inorder print */ static void treeprint2(struct tnode *p) { if (p != NULL) { treeprint2(p -> left); printf("%c", p -> ch); treeprint2(p -> right); } } ----------------------------------------- /* tree.h: header file for tree.c */ void insert(char ); void treeprint(void); ----------------------------------------- /* treetest.c: test tree.c */ #include <stdio.h> #include "tree.h" int main() { char c; while ((c = getchar()) != '\n') { insert(c); } treeprint(); printf("\n"); } % cc -o tree tree.c treetest.c % tree thequickbrownfoxjumpsoverthelazydog abcdefghijklmnopqrstuvwxyz |
I used the above program to randomize the word file on the Sun Unix system. Here is the original word file: Original word list, and here is the randomized version: Randomized word list. (Each file has 25143 words in 206663 bytes.)
Requirements for Part A |
---|
|
Requirements for Part B |
---|
|
Requirements for Part C |
---|
|
Diagram illustrating the tree of Part C with 3 nodes |
---|
![]() |
Notice above that in addition to the binary search tree, this structure also includes pointers that connect all nodes into a bi-directional list in alphabetic order. Thus the code in the second column below will print all the words of the tree in alphabetic order, and the code in the third column will print the words in reverse alphabetic order. (This assumes that the data field has been renamed char *w;.)
Node: tnode | Printing in order | Printing in reverse |
---|---|---|
struct tnode { char *w; struct tnode *left; struct tnode *right; struct tnode *prev; struct tnode *next; }; | void printfromfirst(void) { struct tnode *p = first; while (p != NULL) { printf("%s\n", p -> w); p = p -> next; } } | void printfromlast(void) { struct tnode *p = last; while (p != NULL) { printf("%s\n", p -> w); p = p -> prev; } } |
The most difficult part of this recitation is adjusting all the pointers when you add a node: a part of the rewritten insert function. The diagram below illustrates adding a fourth node to the tree of the previous diagram. After inserting Jan, Feb, and Mar, the diagram shows the insertion of Jun (not the order you would use from the months file). All the changes are in red. Here in addition to what was done before, one has to add new values for one prev and one next field, as well as changing the values in one prev and one next field. A new node added at the right is very similar. In the case of a node added at the far left (to the left of a node with prev field null), you only need to add two new values, and none need to be changed. The first pointer also has to have its value changed. The situation for a node added at the far right is similar.
After the first insertion (sort of a special case), you should have a single node, with all three pointers root, first, and last pointing to it, and with its prev and next fields null.
The pointer manipulations are fairly complicated. For a change this part of my code worked the first time I tried it, but I was very careful in drawing the diagrams and in writing out the statements.
Diagram showing the addition of a 4th node to the tree |
---|
![]() |
Sample Output | |
---|---|
Using file months | Using file ranwords_unix |
% cc -o treetest tree.c treetest.c % treetest Enter word to look up ---> Jul Apr Aug Dec Feb Jan Jul <---- Jun Mar May Nov Oct | % cc -o treetest tree.c treetest.c % treetest Enter word to look up ---> foxtail fox foxglove Foxhall foxhole foxhound foxtail <---- foxy foyer FPC fraction fractionate |
Contents of email submission
for Recitation 12: Last Name, First Name; Course Number; Recitation Number. a. Code and results for Part A. b. Code and results for Part B. c. Code and results for Part C.
|