training

Code I wrote during training
git clone git://git.bitsmanent.org/training
Log | Files | Refs | README

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