1 Linear Collections Objects that store Objects in a line.
-
Upload
estella-thompson -
Category
Documents
-
view
225 -
download
3
Transcript of 1 Linear Collections Objects that store Objects in a line.
1
Lin
ear
Col
lect
ions
Objectsthat storeObjectsin a line
Object-Oriented Design
A technique for developing a program in which the solution is expressed in terms of objects -- self- contained entities composed of data and operations on that data.
Private data
<<
setf...
Private data
>>
get...
ignore
cin cout
More about OOD
Languages supporting OOD include: C++, Java, Smalltalk, Eiffel, and Object-Pascal.
A class is a programmer-defined data type and objects are variables of that type.
In C++, cin is an object of a data type (class) named istream, and cout is an object of a class ostream. Header files iostream.h and fstream.h contain definitions of stream classes.
Procedural vs. Object-Oriented Code
“Read the specification of the software you want to build. Underline the verbs if you are after procedural code, the nouns if you aim for an object-oriented program.”
Brady Gooch, “What is and Isn’t Object Oriented Design,” 1989.
5
Objects• Objects are:
– Building blocks and tools that interact to produce an outcome• Objects Have:
– Attributes• These define the object
– Actions• These are the tasks the object can perform
6
Structs vs. Classes
Similarities
1. Essentially the same syntax
2. Both are used to model objects with different attributes
(characteristics) represented as data members
(also called fields or instance or attribute variables).
Thus, both are used to process non-homogeneous data sets.
7
Structs vs. Classes
Differences
1. C does not provide classes; C++ provides both structs and classes.
2. Members of a struct by default are public (can be accessed outside the struct by using the dot operator.In C++ they can be declared to be private (cannot be accessed outside the struct.
3. Members of a class by default are private (cannot be accessed outside the class) but can be explicitlydeclared to be public.
8
C Structs vs. C++ Classes (& Structs)("traditional" vs "OOP")
Structs have: Attributes (characteristics) represented as
and, C++ structs and classes can also have:
Attributes
Data Members
Operations
Function Members
This leads to a whole new style of programming: object-oriented. Objects are self-contained,possessing their own operations — commonly called the I can do it myself principle — rather than being passed as a parameter to an external function that operates on them and sends them back.
Operations (behaviors) represented as (also called methods).
data members
function members
9
C++ class data type
• A class is an unstructured type that encapsulates a fixed number of data components (data members) with the functions (called member functions) that manipulate them.
• The predefined operations on an instance of a class are whole assignment and component access.
10
class DateType Specification
// SPECIFICATION FILE ( datetype.h )
class DateType // declares a class data type{
public : // 4 public member functions
void Initialize ( int newMonth , int newDay , int newYear ) ;int YearIs( ) const ; // returns yearint MonthIs( ) const ; // returns monthint DayIs( ) const ; // returns day
private : // 3 private data members
int year ; int month ; int day ;
} ;
10
11
Use of C++ data type class
• Variables of a class type are called objects (or instances) of that particular class.
• Software that declares and uses objects of the class is called a client.
• Client code uses public member functions (called methods in OOP) to handle its class objects.
• Sending a message means calling a public member function.
12
Client Code Using DateType#include “datetype.h” // includes specification of the class#include “bool.h”
int main ( void ){
DateType startDate ; // declares 2 objects of DateType DateType endDate ; bool retired = false ;
startDate.Initialize ( 6, 30, 1998 ) ; endDate.Initialize ( 10, 31, 2002 ) ;
cout << startDate.MonthIs( ) << “/” << startDate.DayIs( ) << “/” << startDate.YearIs( ) << endl;
while ( ! retired ) { finishSomeTask( ) ; . . . } }
12
13
2 separate files generally used for class type
// SPECIFICATION FILE ( datetype .h ) // Specifies the data and function members. class DateType { public: . . .
private: . . . } ;
// IMPLEMENTATION FILE ( datetype.cpp ) // Implements the DateType member functions. . . .
14
DateType Class Instance Diagrams
Initialize
YearIs
MonthIs
DayIs
startDate endDate
Private data:
year
month
day
2002
10
31
Initialize
YearIs
MonthIs
DayIs
1998
6
30
Private data:
year
month
day
15
Implementation of DateType member functions
// IMPLEMENTATION FILE (datetype.cpp)#include “datetype.h” // also must appear in client code
void DateType :: Initialize ( int newMonth, int newDay, int newYear )// Post: year is set to newYear.// month is set to newMonth.// day is set to newDay.{
year = newYear ; month = newMonth ; day = newDay ;}
15
int DateType :: MonthIs ( ) const
// Accessor function for data member month
{
return month ;
}
int DateType :: YearIs ( ) const
// Accessor function for data member year
{
return year ;
}
int DateType :: DayIs ( ) const
// Accessor function for data member day
{
return day ;
} 16
17
Abstract Data Types (ADTs)
• An Abstract Data Type is an abstraction of a data structure. (No coding is involved.)
• The ADT specifies:– what can be stored in the ADT
– what operations can be done on/by the ADT
• For example, if we are going to model a bag of marbles as an ADT, we could specify that:– this ADT stores marbles
– this ADT supports putting in a marble and getting out a marble.
18
Abstract Data Types (ADTs)
• There are lots of formalized and standard ADTs. (A bag of marbles is not one of them.)
• In this course we are going to learn a lot of different standard ADTs. (stacks, queues, trees...)
19
List Abstract Data Type• Overview
– An ordered linear collection– Dynamic (grows/shrinks as needed)
• What operations should lists support?
– print– clear– find– remove– add– insert– size– …
20
Implementation
• Sequential Implementation– Uses arrays to store and manipulate data– Wasted memory (unused slots)– Fast random access is supported
• Linked Implementation– No unused slots– Uses recursively-defined nodes to impose a linear
structure on the data– Slow random access
21
List Implementation• Sequential Implementation (using arrays)
– Use an array to hold data elements
– Has a “fixed” capacity with (probably many) wasted slots. Some insertions require O(n) even from the end of the list.
– Keep track of the size of the list explicitly.
0
size
data
22
Code Exampleclass MyVector { private Object data[]; private int size; private int increment; private static final int DEFAULT_CAPACITY = 250; private static final int DEFAULT_INCREMENT = 250;
// increment and capacity should be greater than 0 MyVector(int cap, int incr) { data = new Object[cap]; increment = incr; size = 0; }
public int size() { return size; }
public void add(Object obj) { if(size == data.length) { resize(); } data[size++] = obj; }
…}
class MyVector { private Object data[]; private int size; private int increment; private static final int DEFAULT_CAPACITY = 250; private static final int DEFAULT_INCREMENT = 250;
// increment and capacity should be greater than 0 MyVector(int cap, int incr) { data = new Object[cap]; increment = incr; size = 0; }
public int size() { return size; }
public void add(Object obj) { if(size == data.length) { resize(); } data[size++] = obj; }
…}
0
size
data
23
Array-Based Implementation• Some Pseudo-Code:
Algorithm add(r,e):for i = n - 1, n - 2, ... , r do
S[i+1] s[i]S[r] en n + 1
Algorithm remove(r):e S[r]for i = r, r + 1, ... , n - 2 do
S[i] S[i + 1]n n - 1return
24
Array-based List Performance
Run-time performanceMethod
O(n)Object remove(int index)
O(n)int indexOf(Object element)
O(1)Object set(int index, Object element)
O(1)Object get(int index)
O(1) or O(n)void clear()
O(1)boolean add(Object element)
O(n)void add(int index, Object element)
25
List Implementation• Singly-Linked Implementation:
– Uses a recursively-defined “list node” structure to hold data elements
– Has dynamic capacity with little “wasted” memory
– Keep track of the “head” node and can access all other nodes
– “Natural” operations are from the front since they are “fast”
Next
Data
Next
Data
Next
Data
Head Node
26
Singly-Linked List Performance
Run-time performanceMethod
O(n)Object remove(int index)
O(n)int indexOf(Object element)
O(n)Object set(int index, Object element)
O(n)Object get(int index)
O(1)void clear()
O(1)boolean add(Object element)
O(n)void add(int index, Object element)
27
List Implementation• Doubly-Linked Implementation:
– Uses a recursively-defined “list node” structure to hold data elements
– Has dynamic capacity with little “wasted” memory
– Keep track of the “head” and “tail” nodes and can access all other nodes
– “Natural” operations are from the head and tail since they are “fast”
Next
Prev
Head Node
Data
Next
Prev
Data
Next
Prev
Data
Tail Node
28
Implementation with a Doubly Linked List
the list before insertion
creating a new node for insertion:
the list after insertion:
29
Implementation with a Doubly Linked List
the list before deletion:
deleting a node
after deletion:
30
Doubly-Linked List Performance
Run-time performanceMethod
O(n)Object remove(int index)
O(n)int indexOf(Object element)
O(n)Object set(int index, Object element)
O(n)Object get(int index)
O(1)void clear()
O(1)boolean add(Object element)
O(n)void add(int index, Object element)
31
List Implementation• Sentinal nodes:
– Implementation technique to simplify the code
– Can be used with either doubly or singly linked lists
– Head (and tail) nodes are “dummy” nodes that hold no data
– Head (and tail) nodes never change and are always present
Next
Prev
Head Node
Data
Next
Prev
Data
Next
Prev
Data
Tail Node
“Sentinal” nodes contain no data
32
Stacks• A stack is a container of objects that are inserted and
removed according to the last-in-first-out (LIFO) principle. • Objects can be inserted at any time, but only the last (the
most-recently inserted) object can be removed.• Inserting an item is known as “pushing” onto the stack.
“Popping” off the stack is synonymous with removing an item. :
33
Stack ADT• Basic operations
– push(Object value)• Inserts a value onto the top of the stack
– Object pop()• Removes and returns the top of the stack.
An error occurs if the stack is empty.
• Auxilliary operations– int size()
• returns the number of elements in the stack
– Object top()• returns (but doesn’t remove) the top of
the stack. An error occurs if the stack is empty.
– boolean isEmpty()• returns true if the stack is empty and
false otherwise
Push Pop
Top
34
Stack Implementations• Sequential Implementation:
– Use an array.
– Has a fixed capacity (unless some type of “resize” method is implemented)
– Keep track of the “top” index (the location to place the next inserted item)
– Pop from location “top-1”
index 0 index 11
top
35
Stack Implementations• Linked Implementation:
– Use a list.
– Has a dynamic capacity
– Push/Pop by adding/removing from the beginning/end of the list
Next
Data
Next
Data
Next
Data
Head Node
36
Performance
– Questions to ponder:
–Which implementation has the best runtime performance?
–Which implementation has the best memory usage?
–Which implementation is easier to code?
O(1)O(1)size
O(1)O(1)top
O(1)O(1)isEmpty
O(1)O(1)pop
O(1)O(1)push
LinkedSequentialMethod
37
Queues•A queue differs from a stack in that its insertion and removal routines follows the first-in-first-out (FIFO) principle.•Elements may be inserted at any time, but only the element which has been in the queue the longest may be removed.•Elements are inserted at the rear (enqueued) and removed from the front (dequeued)
38
The Queue Abstract Data Type
•The queue has two fundamental methods:enqueue(o): Insert object o at the rear of the queuedequeue(): Remove the object from the front of the queue and
return it; an error occurs if the queue is empty
•These support methods should also be defined:size(): Return the number of objects in the queueisEmpty(): Return a boolean value that indicates whether the
queue is emptyfront(): Return, but do not remove, the front object in the
queue; an error occurs if the queue is empty
39
An Array-Based Queue•Create a queue using an array in a circular fashion•A maximum size N is specified, e.g. N = 1,000. •The queue consists of an N-element array Q and two integer variables: -f, index of the front element -r, index of the element after the rear one•“normal configuration”
•Questions:What does f=r mean?How do we compute the number of elements in the queue from f and r?
40
Queue Implementations• Sequential Implementation (using “circular” arrays):
– Use an array but imagine it as a “circular” array.– Has a fixed capacity (unless some type of “resize” method is implemented)– Enqueuing is performed at the “end” index.– Dequeuing is performed at the “front” index.
front end
index 0
index 11
index 0 index 11
front end
41
An Array-Based Queue (contd.)Pseudo-Code (cont'd.)
Algorithm size():return (N - f + r) mod N
Algorithm isEmpty():return (f = r)
Algorithm front():if isEmpty() then
throw a QueueEmptyException
return Q[f]
Algorithm dequeue():if isEmpty() then
throw a QueueEmptyException
temp Q[f]Q[f] nullf (f + 1) mod Nreturn temp
Algorithm enqueue(o):if size = N - 1 then
throw a QueueFullException
Q[r] o
42
Implementing a Queue with a Singly Linked List
Nodes connected in a chain by links
The head of the list is the front of the queue, the tail of the list is the rear of the queue. Why not the opposite?
43
Removing at the Head
44
Inserting at the Tail
45
Performance
– Questions to ponder:
–Which implementation has the best runtime performance?
–Which implementation has the best memory usage?
–Which implementation is easier to code?
O(1)O(1)size
O(1)O(1)top
O(1)O(1)isEmpty
O(1)O(1)dequeue
O(1)O(1)enqueue
LinkedSequentialMethod
46
47
Link Inversion
48
49
Exclusive-OR Coded Doubly Linked List
50
51
52
Example of Lists
Problem: Define and implement an ADT for manipulating univariate polynomials.
Problem: Define and implement an ADT for manipulating univariate polynomials.
Let p(x) = anxn + an-1xn-1 + an-2xn-2 + … + a1x1 + a0x0Let p(x) = anxn + an-1xn-1 + an-2xn-2 + … + a1x1 + a0x0
Operations to support:
•add
•multiply
Operations to support:
•add
•multiply
53
Example of Lists
Problem: Define and implement an ADT for manipulating univariate polynomials.
Problem: Define and implement an ADT for manipulating univariate polynomials.
p(x)=3x4+2x+1
q(x)=5x5+2x+2
p(x)=3x4+2x+1
q(x)=5x5+2x+2
Manually produce the result of p*q in order to think about how to write the multiplication code.
15x9+10x6+11x5+6x4+4x2+6x+2
Manually produce the result of p*q in order to think about how to write the multiplication code.
15x9+10x6+11x5+6x4+4x2+6x+2
54
Example of ListsProblem: Define and implement an ADT for manipulating univariate polynomials. Choose a sequential implementation.
Problem: Define and implement an ADT for manipulating univariate polynomials. Choose a sequential implementation.
public class Polynomial {
public static final int MAX_DEGREE = 100;
private int coeffArray[] = new int[MAX_DEGREE+1];
private int highPower;
public Polynomial() {…}
public Polynomial add(Polynomial rhs) {…}
public Polynomial multiply(Polynomial rhs) {…}
public void print() {…}
private void zeroPolynomial() {…}
private void insertTerm(int coefficient, int exp) {…}
private void setDegree(int n) {…}}
public class Polynomial {
public static final int MAX_DEGREE = 100;
private int coeffArray[] = new int[MAX_DEGREE+1];
private int highPower;
public Polynomial() {…}
public Polynomial add(Polynomial rhs) {…}
public Polynomial multiply(Polynomial rhs) {…}
public void print() {…}
private void zeroPolynomial() {…}
private void insertTerm(int coefficient, int exp) {…}
private void setDegree(int n) {…}}
55
Example of Lists
public class Polynomial {
public static final int MAX_DEGREE = 100;
private int coeffArray[] = new int[MAX_DEGREE+1];
private int highPower = 0;
public Polynomial() {
highPower = 0;
}}
public class Polynomial {
public static final int MAX_DEGREE = 100;
private int coeffArray[] = new int[MAX_DEGREE+1];
private int highPower = 0;
public Polynomial() {
highPower = 0;
}}
public Polynomial add(Polynomial rhs) {
Polynomial sum = new Polynomial();
sum.setDegree(max(highPower, rhs.getDegree()));
for(int i = sum.highPower; i >= 0; i-- ) {
sum.coefficients[i] = coefficients[i] + rhs.coefficients[i];
}
return sum;
}
public Polynomial add(Polynomial rhs) {
Polynomial sum = new Polynomial();
sum.setDegree(max(highPower, rhs.getDegree()));
for(int i = sum.highPower; i >= 0; i-- ) {
sum.coefficients[i] = coefficients[i] + rhs.coefficients[i];
}
return sum;
}
Con
stru
ctor
Add
ope
rati
on
56
Example of Listspublic class Polynomial {
public static final int MAX_DEGREE = 100;
private int coeffArray[] = new int[MAX_DEGREE+1];
private int highPower = 0;
public Polynomial multiply(Polynomial rhs) throws OverflowException {
Polynomial product = new Polynomial();
product.setDegree(highPower + rhs.highPower);
if(product.highPower > MAX_DEGREE) {
throw new OverflowException();
}
for(int i=0; i<=highPower; i++) {
for(int j=0; j<=rhs.highPower; j++) {
product.coefficients[i+j] += coefficients[i] * rhs.coefficients[j];
}
}
return product;
}
}}
public class Polynomial {
public static final int MAX_DEGREE = 100;
private int coeffArray[] = new int[MAX_DEGREE+1];
private int highPower = 0;
public Polynomial multiply(Polynomial rhs) throws OverflowException {
Polynomial product = new Polynomial();
product.setDegree(highPower + rhs.highPower);
if(product.highPower > MAX_DEGREE) {
throw new OverflowException();
}
for(int i=0; i<=highPower; i++) {
for(int j=0; j<=rhs.highPower; j++) {
product.coefficients[i+j] += coefficients[i] * rhs.coefficients[j];
}
}
return product;
}
}}
Mul
tipl
icat
ion
57
Example of Lists
public class PolynomialClient {
public static void main(String[] args) {
Polynomial p1 = new Polynomial();
Polynomial p2 = new Polynomial();
…????…
Polynomial p3 = p1.multiply(p2);
System.out.println(p3);
}
}
public class PolynomialClient {
public static void main(String[] args) {
Polynomial p1 = new Polynomial();
Polynomial p2 = new Polynomial();
…????…
Polynomial p3 = p1.multiply(p2);
System.out.println(p3);
}
}
Problem: Write a program to multiply two polynomials and print the result. The two polynomials should be 3x2 + 2x and 4x4 + 3x3 + 12.
Problem: Write a program to multiply two polynomials and print the result. The two polynomials should be 3x2 + 2x and 4x4 + 3x3 + 12.
58
Example of Listspublic class Polynomial {
public static final int MAX_DEGREE = 100;
private int coeffArray[] = new int[MAX_DEGREE+1];
private int highPower = 0;
public void setCoefficient(int power, int coefficient)
throws OverflowException, UnderflowException {
if(power > MAX_DEGREE) {
throw new OverflowException();
} else if(power < 0) {
throw new UnderflowException();
} else if(power > getDegree()) {
setDegree(power);
}
coeffArray[power] = coefficient;
}
}
public class Polynomial {
public static final int MAX_DEGREE = 100;
private int coeffArray[] = new int[MAX_DEGREE+1];
private int highPower = 0;
public void setCoefficient(int power, int coefficient)
throws OverflowException, UnderflowException {
if(power > MAX_DEGREE) {
throw new OverflowException();
} else if(power < 0) {
throw new UnderflowException();
} else if(power > getDegree()) {
setDegree(power);
}
coeffArray[power] = coefficient;
}
}
Aux
illi
ary
Met
hod
59
Example of Lists
public class PolynomialClient {
public static void main(String[] args) {
Polynomial p1 = new Polynomial();
Polynomial p2 = new Polynomial();
p1.setCoefficient(2,3);
p1.setCoefficient(1,2);
p2.setCoefficient(4,4);
p2.setCoefficient(3,3);
p2.setCoefficient(0,12);
Polynomial p3 = p1.multiply(p2);
System.out.println(p3);
}
}
public class PolynomialClient {
public static void main(String[] args) {
Polynomial p1 = new Polynomial();
Polynomial p2 = new Polynomial();
p1.setCoefficient(2,3);
p1.setCoefficient(1,2);
p2.setCoefficient(4,4);
p2.setCoefficient(3,3);
p2.setCoefficient(0,12);
Polynomial p3 = p1.multiply(p2);
System.out.println(p3);
}
}
Problem: Write a program to multiply two polynomials and print the result. The two polynomials should be 3x2+2x and 4x4+3x3+12.
Problem: Write a program to multiply two polynomials and print the result. The two polynomials should be 3x2+2x and 4x4+3x3+12.
60
Example of Lists
public class PolynomialClient {
public static void main(String[] args) {
Polynomial p1 = new Polynomial();
Polynomial p2 = new Polynomial();
p1.setCoefficient(5000,10);
p1.setCoefficient(0,1);
p2.setCoefficient(2,2);
p2.setCoefficient(0,2);
Polynomial p3 = p1.multiply(p2);
System.out.println(p3);
}
}
public class PolynomialClient {
public static void main(String[] args) {
Polynomial p1 = new Polynomial();
Polynomial p2 = new Polynomial();
p1.setCoefficient(5000,10);
p1.setCoefficient(0,1);
p2.setCoefficient(2,2);
p2.setCoefficient(0,2);
Polynomial p3 = p1.multiply(p2);
System.out.println(p3);
}
}
Consider: Write a program to multiply two polynomials and print the result. The two polynomials are 10x5000+1 and 2x2+2. What is the run-time?
Consider: Write a program to multiply two polynomials and print the result. The two polynomials are 10x5000+1 and 2x2+2. What is the run-time?
61
Example of Lists
public class Polynomial {
public static final int MAX_DEGREE = 100;
private List coeffs = new LinkedList();
private in highPower;
private static class Term {
int coefficient;
int exponent;
Term(int c, int e) {
coefficient = c;
exponent = e;
}
}
public Polynomial() {…}
public Polynomial add(Polynomial rhs) {…}
public Polynomial multiply(Polynomial rhs) {…}
public void print() {…}
private void zeroPolynomial() {…}
private void insertTerm(int coefficient, int exp) {…}
private void setDegree(int n) {…}}
public class Polynomial {
public static final int MAX_DEGREE = 100;
private List coeffs = new LinkedList();
private in highPower;
private static class Term {
int coefficient;
int exponent;
Term(int c, int e) {
coefficient = c;
exponent = e;
}
}
public Polynomial() {…}
public Polynomial add(Polynomial rhs) {…}
public Polynomial multiply(Polynomial rhs) {…}
public void print() {…}
private void zeroPolynomial() {…}
private void insertTerm(int coefficient, int exp) {…}
private void setDegree(int n) {…}}
Problem: Define and implement an ADT for manipulating univariate polynomials. Choose a linked implementation.
Problem: Define and implement an ADT for manipulating univariate polynomials. Choose a linked implementation.
62
Linked Lists for Polynomials
Linked lists woulddefinitely be a good alternative to arraysfor sparse polynomials.
P1
10 1000 5 14 1 0
3 1990 1492-2 11 1 5 0P2
Each node has the coefficient, theexponent, and the pointer to next.
63
Comparison of the Two Implementations
O(x*y)
O(x+y)
O(x*y)
O(x+y)
ListList ArrayArray
O(m*n)??O(m*n)multiplication (p * q)
O(Max(m,n))O(Max(m, n))addition (p + q)
SpaceTimeMethod
m = Degree(p)n = Degree(q)x = number of non-zero coefficients in py = number of non-zero coefficients in q
64
List Example(Radix sort)
Sort the following values using a base-8 radix sort.
Value Binary Form
123 001111011
1 000000001
215 011010111
117 001110101
56 000111000
89 001011001
212 011010100
184 010111000
5 000000101
65
Using Lists for a Radix Sort
• Used to be called a “card sort”, back in the dinosaur days of old-style punch cards.
• The idea is to throw items that need to be sorted into buckets.– Sort the list (13, 9, 10, 3, 1, 15, 4, 7, 12)
151312109741 3
There are 15 buckets in this array
66
Another Example
• Sort (64, 8, 216, 512, 27, 729, 0, 1, 343, 125). Use three passes of the radix sort with only 10 buckets!
82721664512
827
21664
512
1
2764
512
Sort by 1’s digit
Sort by 10’s digit
Sort by 100’s digit
Each arraylocation storesa linked list ofinteger items.
34310 125 729
8 216
1
0
729
729
0
125
125
343
343
67
Time Complexity of Radix Sort• If P is the number of passes, N is the
number of elements to sort, and B is the number of buckets, then the running time is O(P(N+B)).
68
Use Multilists Instead
S1
S2
Sn
C1 Cm
69
Applications of Stacks
• Examining programs to see if symbols balance properly.
• Performing “postfix” calculations.
• Performing “infix” to “postfix” conversions.
• Function calls (and especially recursion) rely upon stacks.
70
Symbol Balancing
• A useful tool for checking your code is to see if the (), {}, and [] symbols balance properly.– For example the sequence …[…(…)…]… is
legal but the sequence …[…(…]…)… is not.– The presence of one misplaced symbol can
result in hundreds of worthless compiler diagnostic errors!
71
Symbol Balancing Algorithm
• The algorithm is simple and efficient O(N):– Make an empty stack.– Read characters until end of file (EOF).– If the character is an opening symbol ([{, push it
onto the stack.– If it is a closing symbol )]}, then if the stack is
empty report an error. Otherwise pop the stack.– If the symbol popped is not the corresponding
opening symbol, report an error.– At EOF, if the stack is not empty report an error.
72
Stack ExampleProblem: Determine if a given mathematical expression is parenthetically balanced. Expressions are parenthetically balanced if each left-parenthesis is closed after all enclosed parenthetic expressions have been closed and no unmatched parenthesis remain.
Problem: Determine if a given mathematical expression is parenthetically balanced. Expressions are parenthetically balanced if each left-parenthesis is closed after all enclosed parenthetic expressions have been closed and no unmatched parenthesis remain.
Examples:(3 + 4 * (5/2))(3 + 8) * 5/2)(3 + (8 * ( 4 – 2))
Examples:(3 + 4 * (5/2))(3 + 8) * 5/2)(3 + (8 * ( 4 – 2))
algorithm isBalanced(exp)
INPUT: An expression
OUTPUT: True if the expression is parenthetically
balanced and false otherwise
Let S be a stack
for every token t in exp (scanning from left to right)
if t is a left-parenthesis then
S.push(t)
else if t is a right-parenthesis then
if S.pop() is not a left-parenthesis then
return false
return S.isEmpty()
73
Stack ExampleParenthesis balancing is incorporated into most text editors and HTML verification programs.
HTML documents consist of tagged items. Tags must be properly nested (or balanced). The parenthesis balancing algorithm can be easily extended to check that HTML tags are properly balanced
<html> <head><title>Simple HTML File</title></head> <body> <b>Some text goes here</b> <table> <tr><td>One</td><td>Two</td></tr> </table> </body> </html>
<html> <head><title>Simple HTML File</title></head> <body> <b>Some text goes here</b> <table> <tr><td>One</td><td>Two</td></tr> </table> </body> </html>
74
Expression ExampleFully parenthesized expressions have parenthesis surrounding each infix expression. For example (((3.1 + 1.0) * 5.0) / 12.3) is fully parenthesized while the expression ((3.1 + 12) - 18) + 6 is not.
Write an algorithm to evaluate a fully parenthesized expression.
algorithm evaluate(exp) INPUT: A fully parenthesized expression OUTPUT: A number that is the result of evaluating the input expression
Let S be a stack for every token t in exp (scanning left to right) if t is a number or operator S.push(t) else if t is a right paren y = S.pop() op = S.pop() x = S.pop() S.push(x op y) if S.size() is equal to 1 return S.pop() else an error occurs
algorithm evaluate(exp) INPUT: A fully parenthesized expression OUTPUT: A number that is the result of evaluating the input expression
Let S be a stack for every token t in exp (scanning left to right) if t is a number or operator S.push(t) else if t is a right paren y = S.pop() op = S.pop() x = S.pop() S.push(x op y) if S.size() is equal to 1 return S.pop() else an error occurs
75
Postfix Calculator• What is “postfix”?
– It is the most efficient method for representing arithmetic expressions.
– With “infix” (the method you are used to) you put operators between operands: a + b.
– With “postfix” you put operators after operands: a b +.
– There is never any need to use ()’s with postfix notation. There is never any ambiguity.
– There is yet another notation: “prefix”. Do you know what that is?
76
Postfix Example• This example is in infix:
a + b * c + (d * e + f) * g
• In postfix this is:a b c * + d e * f + g * +
b*c
a + b*cd*e
f + d*e
g * (f + d*e)
(a + b*c) + (g * (f + d*e))
77
Postfix Calculator Algorithm• The algorithm is simple and efficient O(N):
– Read in input.– If input is an operand, push on stack.– If input is an operator, pop top two operands off
stack, perform operation, and place result on stack.
• Example: a b c * +– Push a, b, and then c on the stack.– Pop c and b, perform multiplication, and push result.– Pop (b*c) and a, perform addition, and push result.
78
Expression ExampleA postfix expression is an expression where the operator always follows the operands. For example 3 5 + evaluates to 8 and is written in postfix form.
algorithm evaluate(exp) INPUT: A String exp that is a postfix expression OUTPUT: A number that is the result of evaluating the input expression
Let S be a stack for every token t in exp (scanning left to right) if t is a number S.push(t) else x = S.pop() y = S.pop() S.push(y t x) // apply operation t to operands y and x
if S.size() is equal to 1 return S.pop() else an error occurs
algorithm evaluate(exp) INPUT: A String exp that is a postfix expression OUTPUT: A number that is the result of evaluating the input expression
Let S be a stack for every token t in exp (scanning left to right) if t is a number S.push(t) else x = S.pop() y = S.pop() S.push(y t x) // apply operation t to operands y and x
if S.size() is equal to 1 return S.pop() else an error occurs
79
Infix to Postfix Conversion
• Surprisingly, one only needs a stack to write an algorithm to convert an infix expression to a postfix expression.– It can handle the presence of ()’s.– It is efficient: O(N).
80
Conversion Algorithm
• The algorithm is reasonably simple:– Read infix expression as input.
– If input is operand, output the operand.
– If input is an operator +, -, *, /, then pop and output all operators of >= precedence. Push operator.
– If input is (, then push.
– If input is ), then pop and output all operators until see a ( on the stack. Pop the ( without output.
– If no more input then pop and output all operators on stack.
81
Expression ExampleInfix expressions are where the operator occurs between the operands. This is the kind of representation for mathematical expressions that we are accustomed to..
algorithm infixToPostfix(exp) INPUT: A String exp that is a postfix expression OUTPUT: A postfix expression that is equivalent to the infix input
Let S be a stack for every token t in exp (scanning left to right) if t is a left-paren S.push(t) else if t is a number print t else if t is an operator print S.pop() until one of the following occurs 1) The stack S becomes empty 2) S.top() is a left paren 3) S.top() has a lower precedence than the current operator when one of these 3 things occurs then S.push(t) else if t is a right-paren print S.pop() until S.top() is a left-paren S.pop() and ignore the left-paren print S.pop() until the stack S is empty
algorithm infixToPostfix(exp) INPUT: A String exp that is a postfix expression OUTPUT: A postfix expression that is equivalent to the infix input
Let S be a stack for every token t in exp (scanning left to right) if t is a left-paren S.push(t) else if t is a number print t else if t is an operator print S.pop() until one of the following occurs 1) The stack S becomes empty 2) S.top() is a left paren 3) S.top() has a lower precedence than the current operator when one of these 3 things occurs then S.push(t) else if t is a right-paren print S.pop() until S.top() is a left-paren S.pop() and ignore the left-paren print S.pop() until the stack S is empty
82
Conversion Example
• Infix:a + b * c + (d * e + f) * g
• In postfix this is:a b c * + d e * f + g * +
• Try to follow the algorithm to obtain the right postfix expression.
83
Details of Example
+*+ +
(+
*(+
+(+ +
*+
Output:
Stack:
a b c * + d e * f + g * +
Arrows representpop and output
Arrows representpop and output
84
Function Calls
• In almost all programming languages, calling a function involves the use of a stack.– When there is a function call, all of the important
information (values of variables etc.) is stored on a stack, and control is transferred to the new function.
– This is especially important during recursion.
85
Example
long factorial (int n) { if (n <= 1) return 1; else return n * factorial(n-1);}
Factorial of 5 5 * factorial(4)
Factorial of 44 * factorial(3)
Factorial of 33 * factorial(2)
Factorial of 1Return 1
Factorial of 22 * factorial(1)
1
2
6
24
120
86
Stack Overflow Problems
• The factorial program is an example of “tail recursion”, where the recursive call occurs at the last line of the program.– What if we called factorial(200)? This would
involve having a stack of size 200, which may exceed the stack limit in your operating system (it will also probably exceed the capacity of your integers or even doubles).
– Removal of tail recursion is so simple that some compilers do it automatically.
87
Summary• Linear data structures are linearly ordered collections of
objects. Design and implementation issues of the following ADTs where covered:– Lists
– Stacks
– Queues
• Detailed examples of– Polynomials
– Radix sort
– Parenthesis balancing
– Expression evaluation
Is the semester over yet?