CS3334 Lecture 2: Stacks Overview
CS3334 Lecture 2: Stacks Overview
Lec-2 Stacks
Lecturers & Instructors
• Lecture Instructor:
• Dr. Junqiao QIU, Assist. Prof. at CS, YEUNG Y7708
• Email: junqiqiu@[Link]
• Office Hours: Friday 14:00 - 15:00 or by appointment
• Lab/Tutorial Instructor:
• R11:00 - 11:50 QIU Junqiao
• W13:00 - 13:50 LI Xinyao
• T12:00 - 12:50 HUANG Jiacheng
• F12:00 - 12:50 HUANG Lianming
Exam (60%)
…
};
Review: Abstract Data Type
int * p : (int *) p
*p: dereference (the data pointed by p)
*: multiplication
&a: the address of a
A[]: array variable is a pointer
Review: List
• can be implemented as
• Arrays: statically allocated or dynamically allocated
• Linked Lists: dynamically allocated
• A list can be sorted or unsorted.
Review: Singly Linked List
• Each item in the list is a node
data next
• Linear Structure
first a0 a1 a2 a3 a4 Ù
a0 a2 a1
first
Review: Singly Linked List
// List.h
#include <string>
using namespace std; class List
{
class ListNode public:
{ List( String );
public: List();
ListNode( int ); //various member functions
ListNode( int, ListNode *);
private:
ListNode *get_Next()
{ ListNode *first;
return next; string name;
} }
…
private:
int data;
ListNode *next;
};
Review: Singly Linked List
• Operations:
• InsertNode: insert a new node into a list
• RemoveNode: remove a node from a list
• SearchNode: search a node in a list
• CountNodes: compute the length of a list
• PrintContent: print the content of a list
• …
• All the variables are defined to be “int”, how about when we want to use
“double”?
• Write a different class of list for “double”? Or…
Review: Search for a node
Use a pointer p to traverse the list
• If found: return the pointer to the node,
• otherwise: return NULL.
//[Link]
ListNode* List::Search(int data)
{
ListNode *p=first;
while (p!=NULL)
p
{
if (p->getData()==data)
return p; first ……
p=p->getNext();
}
return NULL;
}
Review: Insert a node
• Data comes one by one, and we want to keep them sorted, how?
• Do search to locate the position
• Insert the new node
• Why is this correct?
newnode newnode
first
first …… ……
…… after remove
first
Review: Remove a node: Case 2
• Remove a node not at the beginning of the list
Current status: q == p->next and the node pointed by q is unwanted
The action we need: p->next=q->next
p q
…… …… before remove
p q
…… …… after remove
Review: Dummy Header Node
• So many cases with Insert and Remove operations
• We want simpler implementations!
• What are the special cases? Why are they different?
• One way to simplify:
• keep an extra node at the front of the list
first ……
newnode newnode
p p
…… …… ……
before remove
p q
…… ……
p q
…… ……
after remove
Review: Remove a node: With Dummy
Header
Void List::RemoveNode(ListNode* q)
{
//remove at the beginning of a list
if (q==first)
first=first->next;
else
//remove not at the beginning
{
ListNode* p=first;
while(p->next!=q)
p=p->next;
p->next=q->next;
}
}
Review: Circular Lists
first a0 a1 a2 a3 a4 Ù
first a0 a1 a2 a3 a4
Review: Circular Lists
first a0 a1 a2 a3
first a0 a1 a2 a3 a4 Ù
p newnode
p newnode
DoublyLinkedList::InsertNode(ListNode *p, ListNode *newnode)
{
newnode->Lnext=p;
newnode->Rnext=p->Rnext;
if(p->Rnext!=NULL) p->Rnext->Lnext=newnode;
p->Rnext=newnode;
}
Review: Doubly Linked List
DoublyLinkedList::RemoveNode(ListNode *p)
{
if(p->Lnext!=NULL) p->Lnext->Rnext=p->Rnext;
if(p->Rnext!=NULL) p->Rnext->Lnext=p->Lnext;
}
Review: Advantages / Disadvantages of
Linked List
Linked allocation: Stores data as individual units and link them by pointers.
Advantages of linked allocation:
• Efficient use of memory
Facilitates data sharing
No need to pre-allocate a maximum size of required memory
No vacant space left
first 1 2 3 4 …… before
first 2 1 4 3 …… after
Exercise 1
Given a singly linked list, find the middle of the linked list.
• For example, if the given linked list is 1->2->3->4->5, then the output
should be 3.
• If there are even nodes, then there would be two middle nodes, we need
to print the second middle element. For example, if the given linked list is
1->2->3->4->5->6, then the output should be 4.
void Stack::pop(Item& x)
{
// assume EmptyStack is a special value
if (size==0)
x=EmptyStack;
else
{
x=array[--size];
if (size <= cap/4)
realloc(cap/2);
}
}
Linked Implementation of Stack
Address T
Top Item E
Top of
Item D e Slot #4: Item E d stack
Item C (slot#4)
Item B
Bottom Item A
d Slot #3: Item D c
#include “stdlib.h”
#include “stdlib.h” {
#include “ListNode.h” class ListNode
{ {
public:
class MyStack
ListNode( int );
{ ListNode( int, ListNode *);
public: ListNode *get_Next()
MyStack( ); {
Pop(); return next;
IsEmpty(); }
Push(int ); …
… private:
private: int data;
ListNode *Top; ListNode *next;
}; };
}
}
Linked Implementation of Stack: push
Push: To insert new information onto Address
the top of the stack p Slot #5: new item e
• Allocate memory for an auxiliary Top
pointer p
e Slot #4: Item E d
• Put new item into p->data
• p->next = T
d Slot #3: Item D c
• T=p
int MyStack::Pop () {
ListNode* p; //a pointer to point to original top node
int rtn_value; //the value of the item to be returned
if (IsEmpty()) //check whether the stack is empty
{ //Exception handling }
rtn_value=Top->data; //save the value to be returned
ListNode* temp = Top;
Top= Top->next; //update the T pointer
delete temp;
return (rtn_value); //return the original top node value
}
Exercise 1
find and remove the largest element in a stack.
// MyStack.h
#include “stdlib.h” int Stack::find_and_Remove_max_val()
{ {
public class Stack ...
{ }
public:
Stack( int );
bool IsEmpty();
bool IsFull(); Input: a stack with 5 2 7 4 (4 is at top)
void push(int ); Output: a stack with 5 2 4 and return 7
int pop();
int top();
private:
int* data;
int top;
int MAXSize;
};
}
Exercise 1 int find_and_Remove_max_val()
{
find and remove the if (isEmpty()) {
cout << "Stack is empty" << endl; return -1;
largest element in a stack. }
while (![Link]()) {
int element = [Link]();
if (element != maxElement)
push(element);
}
return maxElement;
}
Exercise 2
Given string str, we need to print the reverse of individual words.
// MyStack.h
#include “stdlib.h” void printReverseWords (string str)
{ {
public class Stack Stack st;
{ ...
public: }
Stack( int size);
bool IsEmpty();
bool IsFull(); Input: Hello World
void push(char); Output: olleH dlroW
char pop();
char top();
private:
char* data;
int top;
int MAXSize;
};
}
void printReverseWords (string str)
Exercise 2 {
Stack st;
Given string str, we need to print for (int i = 0; i < [Link](); ++i)
the reverse of individual words. {
if (str[i] != ' ')
[Link](str[i]);
else {
while ([Link]() = = false) {
cout << [Link]();
}
cout << " ";
}
}
• Variables needed
• An array memorizing whether a room is visited or not
• A stack
• An array memorizing whether a wall is broken or not
The method:
n Scan the expression from left to right.
n For each symbol, if it is an operand, we store them for later operation (LIFO) push
n If the symbol is an operator, take out the latest 2 operands stored and compute
with the operator. pop pop
Treat the operation result as a new operand and store it. push
n Finally, we can obtain the result as the only one operand stored. pop
Application 3 Evaluation of Postfix Expression
//check whether the parameter symbol is a digit
bool IsDigit(char symbol)
{
if (symbol >= '0' && symbol <= '9’) return true;
return false;
}
int Compute(char operator, int operand1, int operand2)
{
switch (operator)
{ case '+' : return (operand1 + operand2);
case '-' : return (operand1 - operand2);
case '*' : return (operand1 * operand2);
case '/' : return (operand1 / operand2);
}
}
Application 3 Evaluation of Postfix Expression
…
using namespace MyStack
BOOL IsDigit(char symbol) { .. }
int Compute(char operator, int operand1, int operand2) { .. }
void main()
{
int i, operand1, operand2, computed_value
String * exp;
wchar_t c;
//Input of expression: exp
Console::Write(S"Enter the expression (no space in-between): ");
exp=Console::ReadLine();
//Compute the expression
Stack *S=new Stack();
for (i=0; i<exp->GetLength(); i++)
{
c=exp->get_Chars(i);
if (IsDigit(c))
[Link]( (c-'0'));
else
{ operand2=[Link]();
operand1=[Link]();
computed_value=Compute(c,operand1,operand2);
[Link](computed_value);
}
}
//Output the answer
Console::Write(S”Answer: {0}”, [Link]());
}
Application 4 Infix expression->postfix expression
Example:(1+3)*((2-4)+5*7) => 1 3 + 2 4 - 5 7 * + *
Application 4 Infix expression->postfix expression
Example:(1+3)*((2-4)+5*7) => 1 3 + 2 4 - 5 7 * + *
1 3 + 2 4 - 5 7 * + *
4 ) 7 )
2 5 *
- - Ö * * Ö
3 ) ( ( ( x + + + + Ö
1 + + Ö ( ( ( ( ( ( ( x
( ( ( x * * * * * * * * Ö
# # # # # # # # # # #
Exercise 1
Evaluating the following postfix expressions.
2 3 1 * + 9 –
Exercise 2
Remove all duplicate adjacent characters from a string using Stack
// Stack.h
Example
#include “stdlib.h”
Input: str= “azxxzy”
{
Output: ay
public class Stack
{
Input: “aaccdd” public:
Output: Empty String
Stack(int size);
bool IsEmpty();
bool IsFull();
void push(char);
char pop();
string removeDup(string str1){ char top();
Stack st; private:
. . . // insert your codes here char* data;
} int top;
int MAXSize;
};
}
string removeDup(string str1){
• Algorithm:
Sort the lines according to their slopes l1,l2,…ln
Construct a stack and push the first two lines l1,l2 into it
For k=3 to n
{
Pop two lines from the stack and store them in A and B (A stores the first popped line)
While the intersection point of A and B is below lk
{
A=B
Pop a line from the stack and store it in B
}
Push B, A, lk into the stack in this order
}
Identify the boundary of lines
l1
l2
l3
A l23
l4 B l21
• Example:
Processing l3 Processing l4
l3 l4
l2 l2 l2
l1 l1 l1 l1
# # # # # #
Note:
When we use a stack ADT, we should not do anything specific to the internal data
structure. All accesses to the stacks must be made through stack member
functions.
Only the member functions may access the internal data of stacks directly.
Do not access the internal data of stacks in other parts of the programs.
(This note applies also to queue ADT that will be taught in next topic)
Learning Objectives
1. Explain the concepts of Stack
2. Understand the three functions of Stack
3. Able to use the three functions to generate and solve a maze
4. Fully understand how stack is used in Application 2