Advertisement
Zedrimar

Stack With Two Queues (Linked List)

May 8th, 2019
371
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.11 KB | None | 0 0
  1. /***********************************************************
  2. * Author:
  3. * Email:
  4. * Date Created:
  5. * Filename: stack_from_queue.c
  6. *
  7. * Overview:
  8. *   This program is an implementation of a stack using two
  9. *   instances of a queue. The stack functions worked on from
  10. *   Worksheet 17 were re-implemented using the queue functions
  11. *   worked on from Worksheet 18. The main used for testing is
  12. *   included in this file, so that the program is able to be
  13. *   compiled/built and run (see 'Usage').
  14. *   The queue ADT allows for the following behavior:
  15. *       - adding a new link to the back (enqueue)
  16. *       - getting the value of the front
  17. *       - removing the front link (dequeue)
  18. *       - checking if the queue is empty
  19. *   The stack implementation using the queue ADT " ":
  20. *       - adding a new link to the front (push - expensive)
  21. *       - removing the front link (pop)
  22. *       - getting the value of the front link (top)
  23. *       - checking if the stack is empty
  24. *   The criticial piece to utilizing two queues to implement a
  25. *   stack involve using the second queue to properly dequeue
  26. *   the first queue's links when performing a push operation
  27. *   and swapping the first and second queues so the first
  28. *   always represents the actual 'stack'. This makes this op
  29. *   expensive, but then top and pop are easy/efficient ops
  30. *   given that the queue ADT has O(1) access to the front.
  31. *
  32. *   Note that this implementation uses single links, i.e. each
  33. *   link only has a next pointer. Each queue has a head and tail
  34. *   pointer that point to first/last link respectively. Each stack
  35. *   has two queue pointers.
  36. *
  37. * Usage:
  38. *   1) gcc -g Wall -std=c99 -o stack_from_queue stack_from_queue
  39. *   2) ./stack_from_queue
  40. ************************************************************/
  41. #include <assert.h>
  42. #include <stdlib.h>
  43. #include <stdio.h>
  44.  
  45. #ifndef TYPE
  46. #define TYPE int
  47. #endif
  48.  
  49. // Single link
  50. struct Link {
  51.     TYPE value;
  52.     struct Link* next;
  53. };
  54.  
  55. // Single linked list with head and tail pointers
  56. struct Queue {
  57.     struct Link* head;
  58.     struct Link* tail;
  59. };
  60.  
  61. // Stack with two Queue instances
  62. struct Stack {
  63.     struct Queue* q1;
  64.     struct Queue* q2;
  65. };
  66.  
  67.  
  68. /**
  69.     Internal func allocates the queue's sentinel. Sets sentinels' next to null,
  70.     and queue's head and tail to the sentinel.
  71.     param:  queue   struct LinkedList ptr
  72.     pre:    queue is not null
  73.     post:   queue sentinel not null
  74.             sentinel next points to null
  75.             head points to sentinel (always)
  76.             tail points to sentinel (always point to last link unless empty)
  77.  */
  78. void listQueueInit (struct Queue* queue)
  79. {
  80.     /* FIXME: You will write this function */
  81.     assert (queue != NULL);
  82.  
  83.     struct Link* sentinel = (struct Link*)malloc (sizeof (struct Link));
  84.     assert (sentinel != NULL);
  85.  
  86.     sentinel->next = NULL;
  87.     queue->head = sentinel;
  88.     queue->tail = sentinel;
  89. }
  90.  
  91. /**
  92.     Allocates and initializes a queue.
  93.     pre:    none
  94.     post:   memory allocated for new struct Queue ptr
  95.             queue init (call to _initQueue func)
  96.     return: queue
  97.  */
  98. struct Queue* listQueueCreate ()
  99. {
  100.  
  101.     /* FIXME: You will write this function */
  102.     struct Queue* queue = (struct Queue*) malloc (sizeof (struct Queue));
  103.     listQueueInit (queue);
  104.     return queue;
  105. }
  106.  
  107. /**
  108.     Adds a new link with the given value to the back of the queue.
  109.     param:  queue   struct Queue ptr
  110.     param:  value   TYPE
  111.     pre:    queue is not null
  112.     post:   link is created with given value
  113.             link is added after the current last link (pointed to by queue tail)
  114.  */
  115.  
  116. void listQueueAddBack (struct Queue* queue, TYPE value)
  117. {
  118.     /* FIXME: You will write this function */
  119.     assert (queue != NULL);
  120.     assert (queue->tail != NULL);
  121.     struct Link* newLink = (struct Link*) malloc (sizeof (struct Link));
  122.     assert (newLink != NULL);
  123.     newLink->value = value;
  124.     newLink->next = NULL;
  125.     queue->tail->next = newLink;
  126.     queue->tail = newLink;
  127. }
  128.  
  129. /**
  130.     Returns the value of the link at the front of the queue.
  131.     param:  queue   struct Queue ptr
  132.     pre:    queue is not null
  133.     pre:    queue is not empty (i.e., queue's head next pointer is not null)
  134.     post:   none
  135.     ret:    first link's value
  136.  */
  137. TYPE listQueueFront (struct Queue* queue)
  138. {
  139.  
  140.     /* FIXME: You will write this function */
  141.     assert (queue != NULL);
  142.     assert (!listQueueIsEmpty (queue));
  143.     return ((queue->head)->next)->value;
  144. }
  145.  
  146. /**
  147.     Removes the link at the front of the queue and returns the value
  148.     of the removed link.
  149.     param:  queue   struct Queue ptr
  150.     pre:    queue is not null
  151.     pre:    queue is not empty (i.e., queue's head next pointer is not null)
  152.     post:   first link is removed and freed (call to removeLink)
  153.  */
  154.  
  155. TYPE listQueueRemoveFront (struct Queue* queue)
  156. {
  157.     /* FIXME: You will write this function */
  158.     assert (queue != NULL);
  159.     assert (!listQueueIsEmpty (queue));
  160.     struct Link* toDelete;
  161.     toDelete = queue->head->next;
  162.     if (toDelete == queue->tail) {
  163.         queue->tail = queue->head;
  164.     }
  165.     queue->head->next = toDelete->next;
  166.     int retVal = toDelete->value;
  167.     return retVal;
  168.     free (toDelete);
  169. }
  170.  
  171. /**
  172.     Returns 1 if the queue is empty and 0 otherwise.
  173.     param:  queue   struct Queue ptr
  174.     pre:    queue is not null
  175.     post:   none
  176.     ret:    1 if queue head next pointer is null (empty);
  177.             otherwise 0 (not null; not empty)
  178.  */
  179. int listQueueIsEmpty (struct Queue* queue)
  180. {
  181.     /* FIXME: You will write this function */
  182.     assert (queue != NULL);
  183.     assert (queue->tail != NULL);
  184.     if ((queue->head)->next == NULL) {
  185.         return 1;
  186.     }
  187.     else {
  188.         return 0;
  189.     }
  190. }
  191.  
  192. /**
  193.     Deallocates every link in the queue including the sentinel,
  194.     and frees the queue itself.
  195.     param:  queue   struct Queue ptr
  196.     pre:    queue is not null
  197.     post:   memory allocated to each link is freed
  198.             " " sentinel " "
  199.             " " queue " "
  200.  */
  201. void listQueueDestroy (struct Queue* queue)
  202. {
  203.  
  204.     assert (queue != NULL);
  205.     while (!listQueueIsEmpty (queue)) {
  206.         listQueueRemoveFront (queue);
  207.     }
  208.     free (queue->head);
  209.     free (queue);
  210.     queue = NULL;
  211.  
  212. }
  213.  
  214. /**
  215.     Allocates and initializes a stack that is comprised of two
  216.     instances of Queue data structures.
  217.     pre:    none
  218.     post:   memory allocated for new struct Stack ptr
  219.             stack q1 Queue instance init (call to queueCreate func)
  220.             stack q2 Queue instance init (call to queueCreate func)
  221.     return: stack
  222.  */
  223. struct Stack* listStackFromQueuesCreate ()
  224. {
  225.     /* FIXME: You will write this function */
  226.     struct Stack* stack = (struct Stack*) malloc (sizeof (struct Stack));
  227.     stack->q1 = listQueueCreate ();
  228.     stack->q2 = listQueueCreate ();
  229.     return (stack);
  230. };
  231.  
  232. /**
  233.     Deallocates every link in both queues contained in the stack,
  234.     (inc.the sentinel), the queues themselves and the stack itself.
  235.     param:  stack   struct Stack ptr
  236.     pre:    stack is not null
  237.     pre:    queues are not null
  238.     post:   memory allocated to each link is freed along with the
  239.             two queues and stack themselves
  240.  
  241.     Note that I checked that q1 and q2 are not null in this function
  242.     also when I could have just left the assertion to fail in queueDestroy
  243.     if either were pointing to null, but I thought it best to be explicit,
  244.     albeit slightly repetitive.
  245.  */
  246. void listStackDestroy (struct Stack* stack)
  247. {
  248.     assert (stack != NULL);
  249.     assert (stack->q1 != NULL && stack->q2 != NULL);
  250.     listQueueDestroy (stack->q1);
  251.     listQueueDestroy (stack->q2);
  252.     free (stack);
  253.     stack = NULL;
  254. }
  255.  
  256. /**
  257.     Returns 1 if the stack is empty and 0 otherwise.
  258.     param:  stack   struct Stack ptr
  259.     pre:    stack is not null
  260.     post:   none
  261.     ret:    1 if q1 is empty; else, 0
  262.  */
  263. int listStackIsEmpty (struct Stack* stack)
  264. {
  265.  
  266.     /* FIXME: You will write this function */
  267.     assert (stack != NULL);
  268.     if (listQueueIsEmpty (stack->q1)) {
  269.         return 1;
  270.     }
  271.     else {
  272.         return 0;
  273.     }
  274. }
  275.  
  276. /**
  277.     This internal function swaps what q1 and q2 pointers, such that
  278.     q1 points to q2 and q2 points to q1.
  279.     param:  stack   struct LinkedList ptr
  280.     param:  value   TYPE
  281.     pre:    stack is not null
  282.     post:   q1 points to the actual 'stack' with links
  283.  */
  284. void listSwapStackQueues (struct Stack* stack)
  285. {
  286.     /* FIXME: You will write this function */
  287.     assert (stack != NULL);
  288.     struct Queue* temp = stack->q1;
  289.     stack->q1 = stack->q2;
  290.     stack->q2 = temp;
  291. }
  292.  
  293. /**
  294.     Adds a new link with the given value to the back of the Queue q2.
  295.     Then while Queue q1 isn't empty, the first link of the queue is
  296.     dequeued/removed and added to the back of Queue q2, so that in
  297.     the end, Queue q2 has the new order to represent the stack properly
  298.     with the new value at the front of the queue.
  299.     param:  stack   struct LinkedList ptr
  300.     param:  value   TYPE
  301.     pre:    stack is not null
  302.     post:   new link is created w/ given value and added to end of q2
  303.             the first link of q1 is removed and added to end of q2 until
  304.             it's empty
  305.             q1 and q2 are swapped
  306.  */
  307. void listStackPush (struct Stack* stack, TYPE value)
  308. {
  309.     /* FIXME: You will write this function */
  310.     assert (stack != NULL);
  311.     listQueueAddBack (stack->q2, value);
  312.     while (!listQueueIsEmpty (stack->q1))
  313.     {
  314.         TYPE valueTemp = listQueueRemoveFront (stack->q1);
  315.         listQueueAddBack (stack->q2, valueTemp);
  316.     }
  317.     listSwapStackQueues (stack);
  318. }
  319.  
  320. /**
  321.     Removes the link at the top of the stack and returns its value.
  322.     param:  stack   struct Stack ptr
  323.     pre:    stack is not null
  324.     pre:    stack is not empty
  325.     post:   first link is removed and freed (call to removeLink)
  326.     ret:    value of the removed link
  327.  */
  328. TYPE listStackPop (struct Stack* stack)
  329. {
  330.     /* FIXME: You will write this function */
  331.     assert (stack != NULL);
  332.     assert (!listQueueIsEmpty (stack->q1));
  333.     return listQueueRemoveFront (stack->q1);
  334. }
  335.  
  336. /**
  337.     Returns the value of the link at the top of the stack.
  338.     param:  stack   struct Stack ptr
  339.     pre:    stack is not null
  340.     pre:    stack is not empty
  341.     post:   none
  342.     ret:    first link's value
  343.  */
  344. TYPE listStackTop (struct Stack* stack)
  345. {
  346.     /* FIXME: You will write this function */
  347.     assert (!listQueueIsEmpty (stack->q1));
  348.     assert (stack != NULL);
  349.     return listQueueFront (stack->q1);
  350. }
  351.  
  352. /**
  353.     Used for testing the stack from queue implementation.
  354.  */
  355.  
  356. void assertTrue (int pred, char* msg)
  357. {
  358.     printf ("%s: ", msg);
  359.     if (pred)
  360.         printf ("\tPASSED\n");
  361.     else
  362.         printf ("\tFAILED\n");
  363. }
  364.  
  365. int main ()
  366. {
  367.     struct Stack* s = listStackFromQueuesCreate ();
  368.     assert (s);
  369.     printf ("\n-------------------------------------------------\n");
  370.     printf ("---- Testing stack from queue implementation ----\n");
  371.     printf ("-------------------------------------------------\n");
  372.     printf ("stack init...\n");
  373.     assertTrue (listStackIsEmpty (s) == 1, "stackIsEmpty == 1");
  374.  
  375.     printf ("\npushing 4, 5, -300...\n");
  376.     listStackPush (s, 4);
  377.     listStackPush (s, 5);
  378.     listStackPush (s, -300);
  379.  
  380.     assertTrue (listStackIsEmpty (s) == 0, "stackIsEmpty == 0");
  381.     assertTrue (listStackPop (s) == -300, "\npopping; val == -300");
  382.     assertTrue (listStackPop (s) == 5, "popping; val == 5");
  383.     assertTrue (listStackTop (s) == 4, "top val == 4\t");
  384.     assertTrue (listStackPop (s) == 4, "popping; val == 4");
  385.     assertTrue (listStackIsEmpty (s) == 1, "stackIsEmpty == 1");
  386.     // listStackPop(s);     // should fail assert
  387.     // listStackTop(s);     // should fail assert
  388.  
  389.     printf ("\npushing 0-9...\n");
  390.     for (int i = 0; i < 10; i++) {
  391.         listStackPush (s, i);
  392.     }
  393.     assertTrue (listStackTop (s) == 9, "top val == 9\t");
  394.  
  395.     listStackDestroy (s);
  396.  
  397.     return 0;
  398. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement