Cmu Edu
Cmu Edu
Cmu Edu
An array is a random access data structure, where each element can be accessed directly and in constant time. A typical
illustration of random access is a book - each page of the book can be open independently of others. Random access is
critical to many algorithms, for example binary search.
A linked list is a sequential access data structure, where each element can be accesed only in particular order. A typical
illustration of sequential access is a roll of paper or tape - all prior material must be unrolled in order to get to data you
want.
In this note we consider a subcase of sequential data structures, so-calledlimited access data sturctures.
Stacks
A stack is a container of objects that are inserted and removed according to the
last-in first-out (LIFO) principle. In the pushdown stacks only two operations are
allowed: push the item into the stack, and pop the item out of the stack. A stack
is a limited access data structure - elements can be added and removed from the
stack only at the top. push adds an item to the top of the stack,pop removes the
item from the top. A helpful analogy is to think of a stack of books; you can
remove only the top book, also you can add a new book on the top.
Applications
The simplest application of a stack is to reverse a word. You push a given word to stack - letter by letter - and then
pop letters from the stack.
Another application is an "undo" mechanism in text editors; this operation is accomplished by keeping all text changes
in a stack.
Backtracking. This is a process when you need to access the most recent data
element in a series of elements. Think of a labyrinth or maze - how do you find a way
from an entrance to an exit?
Once you reach a dead end, you must backtrack. But backtrack to where? to the
previous choice point. Therefore, at each choice point you store on a stack all possible
choices. Then backtracking simply means popping a next choice from the stack.
Language processing:
space for parameters and local variables is created internally using a stack.
compiler's syntax check for matching braces is implemented by using stack.
support for recursion
Implementation
In the standard library of classes, the data type stack is an adapter class, meaning that a stack is built on top of other data
structures. The underlying structure for a stack could be an array, a vector, an ArrayList, a linked list, or any other
collection. Regardless of the type of the underlying data structure, a Stack must implement the same functionality. This is
achieved by providing a unique interface:
Another implementation requirement (in addition to the above interface) is that all stack operations must run inconstant
time O(1). Constant time means that there is some constant k such that an operation takes k nanoseconds of
computational time regardless of the stack size.
Array-based implementation
Queues
A queue is a container of objects (a linear collection) that are
inserted and removed according to the first-in first-out (FIFO)
principle. An excellent example of a queue is a line of students in the
food court of the UC. New additions to a line made to the back of the
queue, while removal (or serving) happens in the front. In the queue
only two operations are allowed enqueue and dequeue. Enqueue
means to insert an item into the back of the queue, dequeue means
removing the front item. The picture demonstrates the FIFO access.
interface QueueInterface‹AnyType>
{
public boolean isEmpty();
Each of the above basic operations must run at constant time O(1). The following picture demonstrates the idea of
implementation by composition.
Circular Queue
Given an array A of a default size (≥ 1) with two references back and front, originally set to -1 and 0 respectively. Each time
we insert (enqueue) a new item, we increase the back index; when we remove (dequeue) an item - we increase the front
index. Here is a picture that illustrates the model after a few steps:
As you see from the picture, the queue logically moves in the array from left to right. After several moves back reaches the
end, leaving no space for adding new elements
However, there is a free space before the front index. We shall use that space for enqueueing new items, i.e. the next entry
will be stored at index 0, then 1, until front. Such a model is called a wrap around queue or a circular queue
Finally, when back reaches front, the queue is full. There are two choices to handle a full queue:a) throw an exception; b)
double the array size.
The circular queue implementation is done by using the modulo operator (denoted %), which is computed by taking the
remainder of division (for example, 8%5 is 3). By using the modulo operator, we can view the queue as a circular array,
where the "wrapped around" can be simulated as "back % array_size". In addition to the back and front indexes, we
maintain another index: cur - for counting the number of elements in a queue. Having this index simplifies a logic of
implementation.
Applications
The simplest two search techniques are known as Depth-First Search(DFS) and Breadth-First Search (BFS). These two
searches are described by looking at how the search tree (representing all the possible paths from the start) will be
traversed.
Create a stack
Create a new choice point
Push the choice point onto the stack
while (not found and stack is not empty)
Pop the stack
Find all possible choices after the last one tried
Push these choices onto the stack
Return
Create a queue
Create a new choice point
Enqueue the choice point onto the queue
while (not found and queue is not empty)
Dequeue the queue
Find all possible choices after the last one tried
Enqueue these choices onto the queue
Return
1 + ((2 + 3) * 4 + 5)*6
We break the problem of parsing infix expressions into two stages. First, we convert from infix to a different representation
called postfix. Then we parse the postfix expression, which is a somewhat easier problem than directly parsing infix.
Converting from Infix to Postfix. Typically, we deal with expressions in infix notation
2 + 5
where the operators (e.g. +, *) are written between the operands (e.q, 2 and 5). Writing the operators after the operands
gives a postfix expression 2 and 5 are called operands, and the '+' is operator. The above arithmetic expression is called
infix, since the operator is in between operands. The expression
2 5 +
+2 5
Suppose you want to compute the cost of your shopping trip. To do so, you add a list of numbers and multiply them by the
local sales tax (7.25%):
70 + 150 * 1.0725
Depending on the calculator, the answer would be either 235.95 or 230.875. To avoid this confusion we shall use a postfix
notation
70 150 + 1.0725 *
Evaluating a Postfix Expression. We describe how to parse and evaluate a postfix expression.
5 9 3 + 4 2 * * 7 + *
Note, that division is not a commutative operation, so 2/3 is not the same as 3/2.