#include #include #include // btreeintargs.c // from Aspnes notes on binary trees and binary search struct node { int key; struct node *left; /* left child */ struct node *right; /* right child */ }; struct node *makeNode(int key){ struct node * newNode; newNode = malloc(sizeof(*newNode)); assert(newNode); newNode->key = key; newNode->left = NULL; newNode->right = NULL; return newNode; } int treeSize(struct node *root) { if(root == NULL) { return 0; } else { return 1 + treeSize(root->left) + treeSize(root->right); } } int treeHeight(struct node *root) { int lh; /* height of left subtree */ int rh; /* height of right subtree */ if(root == NULL) { return -1; } else { lh = treeHeight(root->left); rh = treeHeight(root->right); return 1 + (lh > rh ? lh : rh); } } /* returns node with given target key */ /* or null if no such node exists */ struct node * treeSearch(struct node *root, int target) { if (! root) { return NULL; } if(root->key == target) { return root; } else if(root->key > target) { return treeSearch(root->left, target); } else { return treeSearch(root->right, target); } } // iterative version struct node * itreeSearch(struct node *root, int target) { while(root != NULL && root->key != target) { if(root->key > target) { root = root->left; } else { root = root->right; } } return root; } void treeInsert(struct node *root, int key) { struct node *newNode; newNode = makeNode(key); for(;;) { if(root->key > key) { /* try left child */ if(root->left) { root = root->left; } else { /* put it in */ root->left = newNode; return; } } else { /* right child case is symmetric */ if(root->right) { root = root->right; } else { /* put it in */ root->right = newNode; return; } } } } void printTreePre(struct node * tree){ if (! tree) { return; } printf("%d [%d] ", tree->key, treeHeight(tree)); printTreePre(tree->left); printTreePre(tree->right); } void printTreeIn(struct node * tree){ if (! tree) { return; } printTreeIn(tree->left); printf("%d [%d] ", tree->key, treeHeight(tree)); printTreeIn(tree->right); } /* how far to indent each level of the tree */ #define INDENTATION_LEVEL (2) /* print contents of a tree, indented by depth */ // uses inorder travesal. Adapted from AVLtree.c static void treePrintIndented(struct node *root, int depth) { int i; if(root != 0) { treePrintIndented(root->left, depth+1); for(i = 0; i < INDENTATION_LEVEL*depth; i++) { putchar(' '); } printf("%d Height: %d Size: %d (%p)\n", root->key, treeHeight(root), treeSize(root), (void *) root); treePrintIndented(root->right, depth+1); } } /* print the contents of a tree */ void treePrint(struct node *root) { treePrintIndented(root, 0); } void treeAdd(struct node * tree, int key){ struct node * newnode; printf("Adding %d\n", key); newnode = treeSearch(tree, key); if (! newnode) { treeInsert(tree, key); } } int main(int argc, char **argv){ printf("Welcome to btree!\n"); struct node * root = makeNode(0); int key; for (int i=1; i < argc; i++) { key = atoi(argv[i]); treeAdd(root, key); printf("Tree height: %d Size: %d\n", treeHeight(root), treeSize(root)); } printf("Preorder: \n"); printTreePre(root); printf("\nInorder: \n"); printTreeIn(root); printf("\nTree:\n"); treePrint(root); printf("\n"); //printf("\nPostorder: \n"); //printTreePost(root); printf("\n"); // does not include treeDestroy. Left as exercise for reader. // hint: use recursion }