The LevAWC Project
 All Data Structures Files Functions Variables Typedefs Enumerations Macros Pages
demo06.c
1 /*
2  * _____
3  * ANSI / ___/
4  * / /__
5  * \___/
6  *
7  * Filename: demo06.c
8  * Author : Dan Levin
9  * Date : Fri Feb 20 11:17:57 2015
10  * Version : 0.51
11  * ---
12  * Description: Usage demo of the binary search tree ADT - in LevAWC.
13  *
14  * Revision history: (this is where you document the diffs between versions...)
15  * Date Revision
16  * 130312 Created this program the first time..
17  * 150206 Made this demo6.c menu-driven.
18  * 150220 Moved some utility functions from here - to file ../utils.c
19  * 150220 Source ready for version 0.5!
20  * 150318 Source ready for version 0.51
21  *
22  */
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <time.h>
27 #include "bitree.h"
28 #include "utils.h"
29 
30 #ifndef OK
31 #define OK 0
32 #endif
33 
34 #ifndef TRUE
35 #define TRUE 1
36 #endif
37 
38 #ifndef FALSE
39 #define FALSE 0
40 #endif
41 
42 #define NR_OF_ITEMS 9
43 
44 /* Some string macros for the main menu... */
45 #define MAIN_MENU_ROW "--- BINARY SEARCH TREE DEMO ---\nMENU: 0=Exit 1=Add_Node 2=Rem_Node 3=Search 4=Print\nSelection "
46 
47 /* FUNCTION-DECLARATIONS */
48 /* Application-specific callbacks */
49 void my_destroy(void *data);
50 void print(const void *data);
51 int my_cmp(const void *key1, const void *key2);
52 
53 /* Functions handling menu selections */
54 void ins_node(BiTree tree);
55 void rem_node(BiTree tree);
56 void search_node(BiTree tree);
57 void print_tree(BiTree tree);
58 void final_status(BiTree tree);
59 
60 /* Misc. application functions.. */
61 void create_nodes(BiTree tree, int nr_of_nodes);
62 /* END-OF-FUNCTION-DECLARATIONS */
63 
64 /* FUNCTION-DEFINITIONS - the rest of the program */
65 /* --- Function: void my_destroy(void *data) --- */
66 void my_destroy(void *data)
67 {
68  free(data);
69 }
70 
71 /* --- Function: void print(const void *data) --- */
72 void print(const void *data)
73 {
74  printf(" %02d", *(int *)data);
75 }
76 
77 /* --- Function: int my_cmp(const int *key1, const int *key2) --- */
78 int my_cmp(const void *key1, const void *key2)
79 {
80  return (*(int *)key1 - *(int *)key2);
81 }
82 
83 /* --- Function: void create_nodes(BiTree tree, int nr_of_nodes) --- */
84 void create_nodes(BiTree tree, int nr_of_nodes)
85 {
86  int i=0, *pi, retval, dupctr=0;
87 
88  do
89  {
90  pi = (int *)malloc(sizeof(int));
91  MALCHK(pi);
92 
93  *pi = rand_int(1,99);
94 
95  if ((retval = BITREEinsert(tree, pi)) != 0) /* Insertion failed... */
96  {
97  if (retval == 1) /* Duplicate key value.. */
98  {
99  dupctr++;
100  my_destroy(pi); /* Free node - since duplicate.. */
101  }
102  else
103  {
104  prompt_and_pause("Fatal error - bailing out..!\n");
105  BITREEdestroy(tree);
106  exit(-1);
107  }
108  }
109  } while (++i < nr_of_nodes);
110 
111  my_clearscrn();
112  printf("--- INITIALIZING A BINARY SEARCH TREE, %d NODES, RANDOM INTEGER DATA ---\n", NR_OF_ITEMS);
113  print_tree(tree);
114  printf("\n\n%d/%d successful insertions -- %d duplicate(s) rejected..", BITREEsize(tree), nr_of_nodes, dupctr);
115  prompt_and_pause("\n\n");
116 }
117 
118 /* --- Function: void insert_nodes(BiTree tree, int nr_of_insertions) --- */
119 void ins_node(BiTree tree)
120 {
121  int tmp, *pi, retval;
122  char mess[BUFSIZ];
123 
124  do
125  {
126  my_clearscrn();
127  printf("--- INSERT NODE ---\n");
128  print_tree(tree);
129 
130  tmp = read_int("\nEnter integer data for node to be inserted (-1=Quit): ", 0, 0);
131 
132  if (tmp == -1)
133  break;
134 
135  pi = (int *)malloc(sizeof(int));
136  MALCHK(pi);
137 
138  *pi = tmp;
139 
140  if ((retval = BITREEinsert(tree, pi)) != 0) /* Insertion failed... */
141  {
142  if (retval == 1) /* Duplicate key value.. */
143  {
144  sprintf(mess, "Error: Duplicate - node %d already present..!", *pi);
145  prompt_and_pause(mess);
146  my_destroy(pi); /* Free node - since being duplicate.. */
147  }
148  else
149  {
150  prompt_and_pause("\nFatal error - bailing out..:!\n");
151  BITREEdestroy(tree);
152  exit(-1);
153  }
154  }
155  else
156  {
157  sprintf(mess, "Node %d will be inserted..", *(int *)pi);
158  prompt_and_pause(mess);
159  }
160  } while (TRUE);
161 }
162 
163 /* --- Function: void remove_nodes(BiTree tree, int nr_of_removes) --- */
164 void rem_node(BiTree tree)
165 {
166  int tmp, *pi, retval;
167  char mess[BUFSIZ];
168 
169  do
170  {
171  my_clearscrn();
172  printf("--- REMOVE NODE ---\n");
173  print_tree(tree);
174 
175  tmp = read_int("\nEnter data for node to be removed (-1=Quit): ", 0, 0);
176 
177  if (tmp == -1)
178  break;
179 
180  pi = &tmp;
181  if ((retval = BITREEremove(tree, (void **)&pi)) != 0) /* Node removal failed.. */
182  {
183  /* Removal didn't work - node NOT found... */
184  if (retval == -1)
185  {
186  sprintf(mess, "Error: Node %d not found..!", *(int *)pi);
187  prompt_and_pause(mess);
188  }
189  else /* Serious failure..(-1 or -2) */
190  {
191  printf("\nFatal failure - bailing out...");
192  BITREEdestroy(tree);
193  exit(retval);
194  }
195  }
196  else
197  {
198  /* Removal succesful - notify user.. */
199  sprintf(mess, "Node %d will be removed..!", *(int *)pi);
200  prompt_and_pause(mess);
201  /* Free node - after being removed from tree.. */
202  my_destroy(pi);
203  }
204  } while (TRUE);
205 }
206 
207 /* --- Function: void search_node(BiTree tree) --- */
208 void search_node(BiTree tree)
209 {
210  int tmp, *pi, retval;
211  char mess[BUFSIZ];
212 
213  do
214  {
215  my_clearscrn();
216  printf("--- SEARCH NODE ---\n");
217  print_tree(tree);
218 
219  tmp = read_int("\nEnter data for node to be found (-1=Quit): ", 0, 0);
220 
221  if (tmp == -1)
222  break;
223 
224  pi = &tmp;
225  if ((retval = BITREElookup(tree, (void **)&pi)) != 0) /* Node searching failed.. */
226  {
227  /* The search didn't work - node NOT found... */
228  if (retval == -1)
229  {
230  sprintf(mess, "Node %d NOT found..!", *(int *)pi);
231  prompt_and_pause(mess);
232  }
233  else /* Compare-callback not set - or serious failure..(-2) */
234  {
235  printf("\nCompare-callback not set - or other fatal failure - bailing out...");
236  BITREEdestroy(tree);
237  exit(retval);
238  }
239  }
240  else
241  {
242  /* Searching succesful - notify user.. */
243  sprintf(mess, "Node %d FOUND..!", *(int *)pi);
244  prompt_and_pause(mess);
245  }
246  } while (TRUE);
247 }
248 
249 /* --- Function: void print_tree(BiTree tree) --- */
250 void print_tree(BiTree tree)
251 {
252  BITREEprint(tree, print);
253  printf("INORDER: ");
254  BITREEinorder(tree, print);
255 }
256 
257 /* --- Function: void final_status(Slist list) --- */
258 void final_status(BiTree tree)
259 {
260  /* Final list status... */
261  my_clearscrn();
262  printf("--- FINAL TREE STATUS ---\n");
263  BITREEprint(tree, print);
264  printf("INORDER: ");
265  BITREEinorder(tree, print);
266 }
267 
268 int main(void)
269 {
270  /* Declare YOUR variables here ! */
271  BiTree mytree;
272  int menu_choice;
273 
274  srand((unsigned int)time(NULL));
275 
276  if ((mytree = BITREEinit(my_destroy)) == NULL)
277  {
278  printf("\nFatal error - bailing out...\n!");
279  BITREEdestroy(mytree);
280  exit(-1);
281  }
282 
283  /* Don't forget to set the compare callback..! */
284  BITREEsetcompare(mytree, my_cmp);
285 
286  /* Initialize - and add nodes to the table... */
287  create_nodes(mytree, NR_OF_ITEMS);
288 
289  do
290  {
291  menu_choice = menu(MAIN_MENU_ROW, 0, 4);
292 
293  switch (menu_choice)
294  {
295  case 1:
296  ins_node(mytree);
297  break;
298  case 2:
299  rem_node(mytree);
300  break;
301  case 3:
302  search_node(mytree);
303  break;
304  case 4:
305  my_clearscrn();
306  printf("--- PRINT TREE ---\n");
307  print_tree(mytree);
308  prompt_and_pause("\n\n");
309  break;
310  default:
311  final_status(mytree);
312  break;
313  }
314  }
315  while (menu_choice);
316 
317  prompt_and_pause("\n\nLet's tidy up and destroy the tree..- Bye!");
318  BITREEdestroy(mytree);
319 
320  return 0;
321 }