A linear-list Data Structure where
- addition of elements to and
- removal of elements from
are restricted to the first element of the list.
the first element of the list
a new element to (the Top of) the
stack.
an element from (the Top of) the
stack (and return it).
the stack (of ints) starts
push(1)
push(2)
push(3)
pop() - returns 3
pop() - returns 2
pop() - returns 1
ast n, irst ut
Describes the order that elements are added
to and removed from a Stack.
- Automatic Memory allocation in a computer
program.
- Editing: allows Undo/Redo
- Web Browsing: allows Back/Forward
- Compilers: used for syntax checking
A linear-list Data structure where
- addition of elements is restricted to the end (rear)
of the list.
- removal of elements is restricted to the
beginning (front) of the list.
first element in the queue
last element in the queue
a new element to (the Rear of)
the Queue.
an element from (the Front
of) the Queue (and return it).
the Queue (of ints) starts
enQ(1)
enQ(2)
enQ(3)
deQ() - returns 1
deQ() - returns 2
deQ() - returns 3
irst n, irst ut
Describes the order that elements are added
to and removed from a Queue.
- Web Server: processing service requests
- Cell Tower: processing data packets from cell
phones.
- OS Scheduling: sharing of a single CPU by
multiple "running" programs.
- Fast Food Drive-Through order processing.
Stacks and Queues may be implemented in a
program using any Linear Data structure,
including:
- Arrays
- Vectors
- Linked Lists
For a Linked List (dynamic) implementation,
the node class would be:
class node {
friend class stack; // or queue
private: node * next = NULL;
string data = "";
};
The node may contain any number of data members needed. Here, there is just one, a string.
After allocating and
populating a new node
(pointed to by n),
we make the new node
the new top.
Left: general case
Right: empty stack caseblue: before Pushing
red: after Pushing
void stack::push(string newdata) {
node * n = new node; // allocate
n->data = newdata; // populate
n->next = top; // connect new node
// to old top.
top = n; // new node is the
} // new top.
Remove the top
node and
deallocate it.
Return the data
from the
popped node.
string stack::pop() {
string oldData = top->data; //save
node * n = top; // pnt to old top
top = top->next; // pnt top to next
delete n; // dealloc old top
return oldData;
}
For a Linked List, the Q class would be:
class queue {
public: void enQ(string newdata);
string deQ();
private:
node * front = NULL;
node * rear = NULL;
};
There are 3 cases we should check for
enqueue and dequeue:
1. empty queue
2. queue of one node
3. queue of two or more nodes
The diagrams in the following slides show the new node already allocated and populated.
Empty
When front and rear are NULL,
the queue is empty.
Just make both front and rear
point to the new node.
1 node in queue
When front and rear both
point to the same node,
there is only one node in the
queue.
No change to front, just
attach the new node after
the current rear and make it
the new rear.
2 or more nodes
When front and rear point to different nodes,
there are 2 or more nodes in the queue.
No change to front, just attach the new node
after the current rear and make it the new rear.
[same action as for queue of 1 node, so these
two cases can be combined for enqueue]
void queue::enQ(string newdata) {
node * n = new node; // allocate
n->data = newdata; // populate
if (front == NULL) { // empty Q
front = n;
rear = n;
}
else { // Q of 1 or more
rear->next = n;
rear = n;
}
empty queue
When front and rear are NULL, the queue is
empty.
There is nothing to remove and return,
so just return some data that means "none",
such as Empty String
queue of one node
Save a copy of the data in
the front node.
Deallocate the one node.
Set both front and rear
to NULL to make it empty.
Return the data.
2 or more nodes
Save a copy of the data in
the front node.
Make front point to the next
node.
Deallocate the old front.
Return the data.
string queue::deQ() {
if (front==NULL) return ""; // empty Q case
node * n = front; // ptr to old front
string oldData = n->data; // save for return
if (front==rear) { // Q of 1 node
front = NULL; // make the queue
rear = NULL; // empty.
}
else // 2 or more nodes
front = front->next; // move front to next
delete n; // dealloc old front
return oldData;
}
We want to write methods that are
and
The four methods written above do:
- allocate, populate and insert [push and enQ]
OR
- save return data, remove, deallocate, return data. [pop and deQ]
In many cases, we need to Push/Enqueue an
already allocated and populated node;
and we may need to use a Popped/Dequeued
node elsewhere instead of destroying it.
So, it would have been better to split these
into at least two methods:
- one that only manipulates pointers
- another that allocates/deallocates and
populates (or saves/returns data),
that invokes the first method.
void stack::push(node * n) { // ptr to node already alloc/pop
n->next = top;
top = n;
}
void stack::push(string newdata) {
node * n = new node; // allocate
n->data = newdata; // populate
push(n); // put on stack
}
Now programmers have a choice:
Just give data, and have it allocated/populated/pushed; OR,
I already have a node with data populated...just push it.
Term Definition
Stack A linear-list Data structure where addition of elements to and
removal of elements from (the list) are restricted to the first
element of the list.
Top First element of a Stack.
Push Stack Operation: add an element to the top.
Pop Stack Operation: remove an element from the top.
LIFO Order of adding/removing items to/from a Stack. Last In, First Out
Queue A linear-list Data structure where addition of elements is restricted
to the end of the list, and removal of elements is restricted to the
beginning of the list.
Front First element of a queue, the next to be removed.
Rear Last element of a queue, the last to be added.
Enqueue Queue Operation: add an element to the rear.
Dequeue Queue Operation: remove an element from the front.
FIFO Order of adding/removing items to/from a Queue. First In, First Out