outputTree.c (7924B)
1 /* Exercise 12.25 */ 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <time.h> 6 7 /* Tree structure */ 8 struct treeNode { 9 struct treeNode *leftPtr; 10 int data; 11 struct treeNode *rightPtr; 12 }; 13 typedef struct treeNode TreeNode; 14 typedef TreeNode *TreeNodePtr; 15 16 /* Queue structure */ 17 struct queue_t { 18 TreeNodePtr data; 19 struct queue_t *next; 20 }; 21 typedef struct queue_t Queue; 22 23 /* 24 * Prototypes 25 */ 26 void insertNode( TreeNodePtr *treePtr, int value ); 27 int deleteNode( TreeNodePtr *treePtr, int value ); 28 29 void enqueue(Queue **head, Queue **tail, TreeNodePtr value); 30 TreeNodePtr dequeue(Queue **head, Queue **tail); 31 32 void outputTree(TreeNodePtr root, int totalSpaces); 33 34 void inOrder( TreeNodePtr treePtr ); 35 void preOrder( TreeNodePtr treePtr ); 36 void postOrder( TreeNodePtr treePtr ); 37 void levelOrder(TreeNodePtr root); 38 39 40 /* 41 * NOTE: this function returns the parent node, not the node in itself. 42 */ 43 TreeNodePtr searchTree( TreeNodePtr treePtr, int value ); 44 45 /* function main begins program execution */ 46 int main(void) 47 { 48 int i; /* counter to loop from 1-10 */ 49 int item; /* variable to hold random values */ 50 TreeNodePtr rootPtr = NULL; /* tree initially empty */ 51 52 srand( time( NULL ) ); 53 printf( "The numbers being placed in the tree are:\n" ); 54 55 /* insert random values between 1 and 15 in the tree */ 56 for ( i = 1; i <= 10; i++ ) { 57 item = 1 + rand() % 10; 58 printf( "%3d", item ); 59 insertNode( &rootPtr, item ); 60 } /* end for */ 61 62 printf("\n\nInsert the value to remove: "); 63 scanf("%d", &item); 64 65 if( deleteNode( &rootPtr, item ) ) { 66 printf("Value not found or value is root: %d\n", item); 67 return -1; 68 } 69 70 /* traverse the tree preOrder */ 71 printf( "\nThe preOrder traversal is:\n" ); 72 preOrder( rootPtr ); 73 74 /* traverse the tree inOrder */ 75 printf( "\n\nThe inOrder traversal is:\n" ); 76 inOrder( rootPtr ); 77 78 /* traverse the tree postOrder */ 79 printf( "\n\nThe postOrder traversal is:\n" ); 80 postOrder( rootPtr ); 81 82 /* traverse the tree levelOrder */ 83 printf( "\n\nThe levelOrder traversal is:\n" ); 84 levelOrder( rootPtr ); 85 86 puts("\n\nShow the tree\n\n"); 87 outputTree(rootPtr, 0); 88 89 putchar('\n'); 90 91 return 0; /* indicates successful termination */ 92 93 } /* end main */ 94 95 /* insert node into tree */ 96 void insertNode( TreeNodePtr *treePtr, int value ) 97 { 98 99 /* if tree is empty */ 100 if ( *treePtr == NULL ) { 101 *treePtr = malloc( sizeof( TreeNode ) ); 102 103 /* if memory was allocated then assign data */ 104 if ( *treePtr != NULL ) { 105 ( *treePtr )->data = value; 106 ( *treePtr )->leftPtr = NULL; 107 ( *treePtr )->rightPtr = NULL; 108 } /* end if */ 109 else { 110 printf( "%d not inserted. No memory available.\n", value ); 111 } /* end else */ 112 113 } /* end if */ 114 else { /* tree is not empty */ 115 116 /* data to insert is less than data in current node */ 117 if ( value <= ( *treePtr )->data ) { 118 insertNode( &( ( *treePtr )->leftPtr ), value ); 119 } /* end if */ 120 121 /* data to insert is greater than data in current node */ 122 else if ( value > ( *treePtr )->data ) { 123 insertNode( &( ( *treePtr )->rightPtr ), value ); 124 } /* end else if */ 125 126 } /* end else */ 127 128 } /* end function insertNode */ 129 130 /* begin inorder traversal of tree */ 131 void inOrder( TreeNodePtr treePtr ) 132 { 133 134 /* if tree is not empty then traverse */ 135 if ( treePtr != NULL ) { 136 inOrder( treePtr->leftPtr ); 137 printf( "%3d", treePtr->data ); 138 inOrder( treePtr->rightPtr ); 139 } /* end if */ 140 141 } /* end function inOrder */ 142 143 /* begin preorder traversal of tree */ 144 void preOrder( TreeNodePtr treePtr ) 145 { 146 147 /* if tree is not empty then traverse */ 148 if ( treePtr != NULL ) { 149 printf( "%3d", treePtr->data ); 150 preOrder( treePtr->leftPtr ); 151 preOrder( treePtr->rightPtr ); 152 } /* end if */ 153 154 } /* end function preOrder */ 155 156 /* begin postorder traversal of tree */ 157 void postOrder( TreeNodePtr treePtr ) 158 { 159 160 /* if tree is not empty then traverse */ 161 if ( treePtr != NULL ) { 162 postOrder( treePtr->leftPtr ); 163 postOrder( treePtr->rightPtr ); 164 printf( "%3d", treePtr->data ); 165 } /* end if */ 166 167 } /* end function postOrder */ 168 169 /* 170 * Delete a node from the tree 171 */ 172 int deleteNode( TreeNodePtr *treePtr, int value ) 173 { 174 TreeNodePtr rm_parentp = searchTree( *treePtr, value ); 175 TreeNodePtr *rm_childp; 176 TreeNodePtr currentPtr; 177 178 /* a simple check */ 179 if( rm_parentp == NULL || *treePtr == NULL ) 180 return 1; 181 182 /* set the "parent" pointer */ 183 if( rm_parentp->leftPtr != NULL && rm_parentp->leftPtr->data == value ) 184 rm_childp = &rm_parentp->leftPtr; 185 else 186 rm_childp = &rm_parentp->rightPtr; 187 188 /* remove a leaf node */ 189 if( ( *rm_childp )->leftPtr == NULL && ( *rm_childp )->rightPtr == NULL ) { 190 191 *rm_childp = NULL; 192 free( *rm_childp ); 193 } 194 /* remove a one-child node: is this code unreadable? :| */ 195 else if(((*rm_childp)->leftPtr != NULL) ^ ((*rm_childp)->rightPtr != NULL)) { 196 197 rm_parentp = *rm_childp; 198 199 if( ( *rm_childp )->leftPtr != NULL ) 200 *rm_childp = ( *rm_childp )->leftPtr; 201 else 202 *rm_childp = ( *rm_childp )->rightPtr; 203 204 free( rm_parentp ); 205 } 206 /* remove a two-children node */ 207 else { 208 currentPtr = ( *rm_childp )->leftPtr; 209 while( currentPtr->rightPtr != NULL ) { 210 currentPtr = currentPtr->rightPtr; 211 } 212 213 rm_parentp = *rm_childp; /* will be freed */ 214 215 currentPtr->rightPtr = ( *rm_childp )->rightPtr; 216 ( *rm_childp )->rightPtr = NULL; 217 *rm_childp = ( *rm_childp )->leftPtr; 218 219 free( rm_parentp ); 220 } 221 222 return 0; 223 } /* eof deleteNode()*/ 224 225 /* 226 * Find a node and returns its daddy 227 */ 228 TreeNodePtr searchTree( TreeNodePtr treePtr, int value ) 229 { 230 TreeNodePtr retp = treePtr; 231 232 if( retp != NULL ) { 233 if( (retp->leftPtr != NULL && retp->leftPtr->data == value) || 234 (retp->rightPtr != NULL && retp->rightPtr->data == value) 235 ) return retp; 236 237 if( retp->data > value ) 238 return searchTree( retp->leftPtr, value ); 239 else 240 return searchTree( retp->rightPtr, value ); 241 } 242 243 return NULL; 244 245 } /* eof searchTree() */ 246 247 /* 248 * Insert a "value" to the queue 249 */ 250 void enqueue(Queue **head, Queue **tail, TreeNodePtr value) 251 { 252 Queue *newqueue; 253 254 if( (newqueue = malloc( sizeof(Queue) )) == NULL ) { 255 printf("Cannot allocate the memory\n"); 256 return; 257 } 258 newqueue->data = value; 259 newqueue->next = NULL; 260 261 /* if the queue is empty */ 262 if( *head == NULL ) { 263 *head = newqueue; 264 } 265 else { 266 ( *tail )->next = newqueue; 267 } 268 269 *tail = newqueue; 270 271 } /* eof enqueue() */ 272 273 /* 274 * Remove an element from the queue and return its value 275 */ 276 TreeNodePtr dequeue(Queue **head, Queue **tail) 277 { 278 TreeNodePtr value; 279 Queue *temp = *head; 280 281 value = ( *head )->data; 282 *head = ( *head )->next; 283 284 /* if the queue is empty */ 285 if( *head == NULL ) { 286 *tail = NULL; 287 } 288 289 free( temp ); 290 291 return value; 292 } /* eof dequeue() */ 293 294 /* 295 * Begin levelorder traversal of tree 296 */ 297 void levelOrder(TreeNodePtr root) 298 { 299 Queue *head = NULL, *tail = NULL; 300 TreeNodePtr currentNode; 301 302 enqueue( &head, &tail, root ); 303 304 while( head != NULL && (currentNode = dequeue(&head, &tail)) != NULL ) { 305 printf("%3d", currentNode->data); 306 307 if( currentNode->leftPtr != NULL ) 308 enqueue(&head, &tail, currentNode->leftPtr); 309 310 if( currentNode->rightPtr != NULL ) 311 enqueue(&head, &tail, currentNode->rightPtr); 312 } 313 } /* eof levelOrder() */ 314 315 /* 316 * Show a binary tree 317 */ 318 void outputTree(TreeNodePtr root, int totalSpaces) 319 { 320 int i; 321 TreeNodePtr currentNode = root; 322 323 while( currentNode != NULL ) { 324 325 outputTree(currentNode->rightPtr, totalSpaces + 5); 326 327 for(i = 1; i <= totalSpaces; i++) 328 putchar(' '); 329 printf("%d\n", currentNode->data); 330 331 currentNode = currentNode->leftPtr; 332 totalSpaces += 5; 333 } 334 335 } /* eof outputTree() */ 336