Stacks and Queues
Stack
A last in, first out (LIFO) data container.
Primary Stack Operations
The primary functions used to manipulate a stack are push and pop. Function push creates a new node and places it on top of the stack. Function pop removes a node from the top of the stack, frees the memory that was allocated to the popped node and returns the popped value.
Stack Structure
// Self-referential structure
typedef struct stackNode
{
int data;
struct stackNode *nextPtr;
}StackNode;
typedef StackNode* StackNodePtr;
Push Function
// Insert a nod at the top of the stack
void push(StackNodePtr *topPtr, int info)
{
StackNodePtr newPtr = (StackNodePtr) malloc(sizeof(StackNode));
if(newPtr != NULL)
{
newPtr->data = info;
newPtr->nextPtr = topPtr;
*topPtr = newPtr;
}
else
{
printf("%d not inserted. No memory available.\n", info);
}
}
Pop Function
// Remove a node from the stack top
int pop(StackNodePtr *topPtr)
{
StackNodePtr tempPtr = *topPtr;
int popValue = (*topPtr)->data;
*topPtr = (*topPtr)->nextPtr;
free(tempPtr);
}
Print Stack
// Print the Stack
void printStack(StackNodePtr currentPtr)
{
if(currentPtr == NULL)
{
puts("The Stack is Empty.\n");
}
else
{
puts("The Stack is:");
while(currentPtr != NULL)
{
printf("%d --> ", currentPtr->data);
currentPtr = currentPtr->nextPtr;
}
puts("NULL\n")
}
}
Queue
A first in, first out (FIFO) data container.
Primary Queue Operations
A queue is similar to a checkout line in a grocery store—the first person in line is serviced first, and other customers enter the line only at the end and wait to be serviced. Queue nodes are removed only from the head of the queue and are inserted only at the tail of the queue. For this reason, a queue is referred to as a first-in, first-out (FIFO) data structure. The insert and remove operations are known as enqueue and dequeue respectively.
Queue Structure
// Self-referential structure
typedef struct queueNode
{
char data;
struct queueNode *nextPtr;
}QueueNode;
typedef QueueNode* QueueNodePtr;
Enqueue Function
// Insert a node at queue tail
void enqueue(QueueNodePtr *headPtr, QueueNodePtr *tailPtr, char value)
{
QueueNodePtr newPtr = (QueueNodePtr) malloc(sizeof(QueueNode));
if(newPtr != NULL)
{
newPtr->data = value;
newPtr->nextPtr = NULL;
// if empty, insert node at head
if(headPtr == NULL)
{
*headPtr = newPtr;
}
else
{
(*tailPtr)->nextPtr = newPtr;
}
*tailPtr = newPtr;
}
else
{
printf("%c not inserted. No memory available.\n", value);
}
}
Dequeue Function
// Remove node from queue head
char dequeue(QueueNodePtr *headPtr, QueueNodePtr *tailPtr)
{
char value = (*headPtr)->data;
QueueNodePtr tempPtr = *headPtr;
*headPtr = (*headPtr)->nextPtr;
// if queue is empty
if(*headPtr == NULL)
{
*tailPtr = NULL;
}
free(tempPtr);
return value;
}
Print Queue
// Print the queue
void printQueue(QueueNodePtr currentPtr)
{
if(currentPtr == NULL)
{
puts("Queue is Empty.\n");
}
else
{
puts("The queue is:");
while(currentPtr != NULL)
{
printf("%c --> ", currentPtr->data);
currentPtr = currentPtr->nextPtr;
}
puts("NULL\n");
}
}
Deque
Deque (Doubly Ended Queue) is a queue like container which is both first in, first out and last in, last out.