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