The LevAWC Project
 All Data Structures Files Functions Variables Typedefs Enumerations Macros Pages
demo05.c
1 /*
2  * _____
3  * ANSI / ___/
4  * / /__
5  * \___/
6  *
7  * Filename: demo05.c
8  * Author : Dan Levin
9  * Date : Fri Feb 20 11:00:53 2015
10  * Version : 0.51
11  * ---
12  * Description: Usage demo for heap and priority queue ADT - in LevAWC.
13  *
14  * Revision history: (this is where you document the diffs between versions...)
15  * Date Revision
16  * 130220 Created this program the first time..
17  * 150124 Converted this file, demo5.c - to be 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 <assert.h>
27 #include <time.h>
28 #include "pqueue.h"
29 #include "slist.h"
30 #include "utils.h"
31 
32 #define NR_OF_ITEMS 16
33 #define NR_OF_REMOVALS 3
34 #define NR_OF_INSERTS 3
35 
36 /* Some string macros for the main menu... */
37 #define MAIN_MENU_ROW "--- HEAP/PRIORITY QUEUE DEMO ---\nMENU: 0=Exit 1=Add_Node 2=Rem_Node 3=Heapsort_Intro 4=Print\nSelection "
38 
39 #ifndef OK
40 #define OK 0
41 #endif
42 
43 #ifndef TRUE
44 #define TRUE 1
45 #endif
46 
47 #ifndef FALSE
48 #define FALSE 0
49 #endif
50 
51 /* FUNCTION-DECLARATIONS */
52 /* Application-specific callbacks */
53 void my_destroy(void *data);
54 int my_chkch(int ch);
55 void print(const void *data);
56 int my_cmp(const void *key1, const void *key2);
57 
58 /* Functions handling menu selections */
59 void add_node(PQueue pq);
60 void rem_node(PQueue pq);
61 void heapsort_intro(PQueue pq);
62 void print_pqueue(PQueue pq);
63 void final_status(PQueue pq);
64 
65 /* Misc. application functions.. */
66 void create_nodes(PQueue pq, int nr_of_ele);
67 void move_nodes(PQueue pq, Slist mylst, int nr_of_moves);
68 /* END-OF-FUNCTION-DECLARATIONS */
69 
70 /* FUNCTION-DEFINITIONS - the rest of the program */
71 /* --- Function: void my_destroy(void *data) --- */
72 void my_destroy(void *data)
73 {
74  free(data);
75 }
76 
77 /* --- Function: int my_chkch(int ch) --- */
78 int my_chkch(int ch)
79 {
80  return strchr("YyNn", ch) ? 1 : 0;
81 }
82 
83 /* --- Function: void print(const void *data) --- */
84 void print(const void *data)
85 {
86  printf(" %02d", *(int *)data);
87 }
88 
89 /* --- Function: int my_cmp(const int *key1, const int *key2) --- */
90 int my_cmp(const void *key1, const void *key2)
91 {
92  return (*(int *)key1 - *(int *)key2);
93 }
94 
95 /* --- Function: void create_nodes(PQueue pq, int nr_of_ele) --- */
96 void create_nodes(PQueue pq, int nr_of_ele)
97 {
98  int i=0, *pi, retval;
99 
100  my_clearscrn();
101  printf("--- INITIALIZING A PRIORITY QUEUE, %d NODES, RANDOM INTEGER DATA ---", NR_OF_ITEMS);
102 
103  do
104  {
105  /* Get a random integer */
106  pi = (int *)malloc(sizeof(int));
107  MALCHK(pi);
108 
109  *pi = rand_int(1,99);
110 
111  /* Insert an integer into priority queue... */
112  retval = PQUEUEinsert(pq, pi);
113  /* Defensive programming... */
114  assert(retval == OK);
115 
116  } while (++i < nr_of_ele);
117 
118  printf("\n\nCurrent queue status -- after %d successful insertions...", PQUEUEsize(pq));
119  PQUEUEprint(pq, print);
120  printf("\nRead \"Tree\" view(above) - columnwise, up-->down - and compare to \"Heap\" view..\n");
121  prompt_and_pause("..do you see any pattern..?");
122 }
123 
124 /* --- Function: void ins_node(PQueue pq) --- */
125 void ins_node(PQueue pq)
126 {
127  int tmp, *pi;
128  char mess[BUFSIZ];
129 
130  do
131  {
132  my_clearscrn();
133  printf("--- INSERT NODES ---");
134  printf("\n\nCurrent priority queue status(%d nodes): ", PQUEUEsize(pq));
135  PQUEUEprint(pq, print);
136 
137  tmp = read_int("\nEnter integer data for node to be inserted (-1=Quit): ", 0, 0);
138 
139  if (tmp == -1)
140  break;
141 
142  pi = (int *)malloc(sizeof(int));
143  MALCHK(pi);
144 
145  *pi = tmp;
146 
147  if ((PQUEUEinsert(pq, pi)) != OK)
148  {
149  printf("\nFatal error enqueing data - exiting...!");
150  PQUEUEdestroy(pq);
151  exit(-1);
152  }
153  else
154  {
155  sprintf(mess, "Node %d will be inserted!", *pi);
156  prompt_and_pause(mess);
157  }
158  } while (TRUE);
159 }
160 
161 /* --- void rem_node(PQueue pq) --- */
162 void rem_node(PQueue pq)
163 {
164  int tmp, *pi, *ptmp;
165  char mess[BUFSIZ], ans;
166 
167  /* Initialize 'tmp'... */
168  tmp = 0;
169 
170  do
171  {
172  my_clearscrn();
173  printf("--- REMOVE NODES ---");
174  printf("\nCurrent priority queue status(%d nodes): ", PQUEUEsize(pq));
175  PQUEUEprint(pq, print);
176 
177  if (tmp == -1)
178  break;
179 
180  ptmp = (int *)PQUEUEpeek(pq);
181 
182  if (ptmp == NULL)
183  {
184  prompt_and_pause("\n\nPriority queue is EMPTY - nothing to do..!");
185  tmp = -1;
186  }
187  else
188  {
189  sprintf(mess, "\nAbout to remove (top) node %d.. - Continue? (y/n): ", *ptmp);
190  ans = read_char(mess, 0, 0, my_chkch);
191 
192  if (ans == 'y' || ans == 'Y')
193  {
194  if ((PQUEUEextract(pq, (void **)&pi)) != OK)
195  {
196  printf("\nFatal error removing data - exiting...!");
197  PQUEUEdestroy(pq);
198  exit(-1);
199  }
200  else
201  {
202  sprintf(mess, "(Top) node %d will be removed!", *pi);
203  prompt_and_pause(mess);
204  my_destroy(pi);
205  }
206  }
207  else
208  tmp = -1;
209  }
210  } while (TRUE);
211 }
212 
213 
214 /* --- Function: void heapsort_intro(PQueue pq) --- */
215 void heapsort_intro(PQueue pq)
216 {
217  int *pv, retval;
218  Slist tmplst;
219 
220  if (PQUEUEsize(pq) == 0)
221  {
222  prompt_and_pause("Priority queue is empty - nothing to do..");
223  return;
224  }
225 
226  /* Initialize a list - defensive programming... */
227  if ((tmplst = SLISTinit(my_destroy)) == NULL)
228  {
229  printf("\nFatal error - bailing out...\n!");
230  PQUEUEdestroy(pq);
231  exit(-1);
232  }
233 
234  do
235  {
236  my_clearscrn();
237  printf("--- HEAPSORT INTRODUCTION ---\n");
238 
239  if (PQUEUEpeek(pq))
240  {
241  /* Print the contents of the priority queue... */
242  PQUEUEprint(pq, print);
243  /* Print the list - from the beginning... */
244  printf("=====");
245  printf("\nList: ");
246  SLISTtraverse(tmplst, print, SLIST_FWD);
247  printf ("\n\nNow - move the high priority node, value=%d, from the priority queue...\n", *(int *)PQUEUEpeek(pq));
248  prompt_and_pause("..and insert it - at the front of the list...");
249  /* Extract the top priority node from the queue... */
250  retval = PQUEUEextract(pq, (void **)&pv);
251  /* Defensive programming... */
252  assert(retval == OK);
253  /* Insert this node at the front of a linked list... */
254  retval = SLISTinsnext(tmplst, NULL, pv);
255  /* Defensive programming... */
256  assert(retval == OK);
257  }
258  else
259  {
260  printf("\nHeap: (empty)");
261  printf("\nTree: (empty)\n");
262 
263  /* Print the list - from the beginning... */
264  printf("=====");
265  printf("\nList: ");
266  SLISTtraverse(tmplst, print, SLIST_FWD);
267  prompt_and_pause("\n\nEvidently - the priority queue is now empty..!");
268  break;
269  }
270 
271  } while (TRUE);
272 
273  printf("\n---\nHey - it looks like the priority queue can be used for sorting things.. :-)!");
274  prompt_and_pause("\nTRUE, indeed! Just Google \'Heapsort\' for more..");
275 
276  /* Move data back from list - to priority queue.. */
277  while (SLISTsize(tmplst))
278  {
279  retval = SLISTremnext(tmplst, NULL, (void **)&pv);
280  assert(retval == OK);
281  retval = PQUEUEinsert(pq, pv);
282  assert(retval == OK);
283  }
284 
285  SLISTdestroy(tmplst);
286 }
287 
288 /* --- Function: void print_pueue(PQueue pq) --- */
289 void print_pqueue(PQueue pq)
290 {
291  my_clearscrn();
292  printf("--- PRINT PRIORITY QUEUE ---");
293  printf("\n\nCurrent priority queue contents(%d nodes): ", PQUEUEsize(pq));
294  PQUEUEprint(pq, print);
295  prompt_and_pause("\n");
296 }
297 
298 /* --- Function: void final_status(Slist list) --- */
299 void final_status(PQueue pq)
300 {
301  my_clearscrn();
302  printf("--- FINAL STATUS ---");
303  printf("\n\nFinal priority queue contents(%d nodes): ", PQUEUEsize(pq));
304  PQUEUEprint(pq, print);
305 }
306 
307 int main(void)
308 {
309  /* Declare YOUR variables here ! */
310  PQueue mypq;
311  int menu_choice;
312 
313  srand((unsigned int)time(NULL));
314 
315  /* Initialize the priority queue and linked list - defensive programming...... */
316  if ((mypq = PQUEUEinit(my_cmp, my_destroy)) == NULL)
317  {
318  printf("\nFatal error - bailing out...\n!");
319  PQUEUEdestroy(mypq);
320  exit(-1);
321  }
322 
323  /* Add initial nodes to the priority queue... */
324  create_nodes(mypq, NR_OF_ITEMS);
325 
326  do
327  {
328  menu_choice = menu(MAIN_MENU_ROW, 0, 4);
329 
330  switch (menu_choice)
331  {
332  case 1:
333  ins_node(mypq);
334  break;
335  case 2:
336  rem_node(mypq);
337  break;
338  case 3:
339  heapsort_intro(mypq);
340  break;
341  case 4:
342  print_pqueue(mypq);
343  break;
344  default:
345  final_status(mypq);
346  break;
347  }
348  }
349  while (menu_choice);
350 
351  prompt_and_pause("\nLet's tidy up and destroy the pr.queue..- Bye!");
352  PQUEUEdestroy(mypq);
353 
354  return 0;
355 }