Abstract Data Types (ADTs) and data structures: terminology and definitions

advertisement
Abstract Data Types (ADTs) and data structures:
terminology and definitions
A type is a collection of values. For example, the boolean type consists of two
values, true and false; the byte type consists of all integers between -127 and
+128.
A data type is a type + a set of operations on data of the type. For example,
integers of type byte plus {+, -, *, /} comprise the data type byte. An integer
array is a data type which has assign and search operations associated with it.
An abstract data type is a data type solely defined in terms of a type and a
set of operations on that type. Each operation is defined in terms of its input
and output without specifying how the data type is implemented. A stack is an
example of an ADT, defined in terms of push and pop operations.
A data structure is an implementation of an ADT. The Stack ADT, for example,
an be implemented by means of an array.
Levels of abstraction in data specification
Any data can be defined in two formats: logical and physical. An ADT defines
data in a logical format -- as a conceptual model, which is completely
independent of its implementation. Consider, for example, a matrix of integers.
At a logical level, we are not interested in how this matrix is implemented. The
only items of interest are what type of data this matrix consists of, and what
operations will be performed on this data.
At a physical level, the associated data structure representing the Matrix ADT
can be implemented with a different degree of abstraction by means of:
–
–
–
a high level language, in which case the Matrix ADT can be defined as
an array of integers.
in assembly language (or byte code) it is represented as a sequence of
words in computer memory.
in machine language it is represented as a sequence of electronic bits.
The Matrix example (cont.)
The ADT Matrix, in more formal terms, can de defined as a collection of data
items of type MatrixData arranged as a rectangular grid, and associated with
the following set of operations:
–
–
Retrieve (M, row#, col#)
Assign (M, row#, col#, value)
To implement the ADT matrix, we can use a two-dimensional array. For
example:
int[ ][ ] M = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {11, 12, 13, 14, 15}}
The retrieve and assign operations can be implemented as follows:
item = M[1][2]
M[2][3] = item
Representation of two-dimensional arrays in
computer memory
Computer memory is a linear sequence of memory cells. There are two ways
to translate a two-dimensional array into a linear sequence:
1. Row by row (this is called the row-major form). To implement assign and
retrieve operations, we must be able to find a particular entry. This can be
done by means of the following formula (called a mapping function):
(# of columns * (i - 1) + j),
where i is the specified row#, and j is the specified col#.
2. Column by column (this is called the column-major form) in which case
the mapping function is
(# of rows * (j - 1) + i).
The Stack ADT
Definition A stack is a restricted list in which entries are added and removed
from the same end, called the top. This strategy is known as last-in-first-out
(LIFO) strategy.
Operations (methods) on stacks:
push (item)
pop ()
size ()
empty ()
full()
ontop()
Inserts item on the top of the stack
Removes the top item
Returns the number of items in the stack
Returns true if the stack is empty
Returns true if the stack is full
Returns the top element without removing it from the stack
There is a built-in class, Stack, in the java.util package, but often it is
desirable to have your own implementation. Next, we discuss a specific
implementation of the Stack ADT.
The Stack Interface in two versions
version 1:
version 2:
public interface Stack {
public interface Stack {
public void push (int item);
public int pop();
public int size();
public boolean empty();
public boolean full();
public int ontop();
public void push (int item)
throws StackFullException;
public int pop() throws StackEmptyException;
public int size();
public boolean empty();
public boolean full();
public int ontop() throws StackEmptyException;
}
}
The Stack ADT -- an array implementation (version 1)
class StackADT implements Stack {
final int MAXSIZE = 100;
private int size;
private int[] stackADT;
private int top = -1;
public StackADT () {
size = MAXSIZE;
stackADT = new int[size];
}
public int pop () {
int i = stackADT[top];
top--;
return i;
}
public boolean empty () {
return (top == -1);
}
public boolean full () {
return (top == size - 1);
}
public StackADT (int inputsize) {
size = inputsize;
stackADT = new int[size];
}
public int ontop () {
int i = pop();
push(i);
return i;
}
public void push (int number) {
top++;
stackADT[top] = number;
}
public int size () {
return (top + 1);
}
}
A note on JAVA exceptions
Exceptions are events occurring during program execution which make
continuation impossible or undesirable.
Examples of exceptions: arithmetic overflow, array reference with index out of
bounds, invalid user entry, etc.
When an exception occurs, an exception handler is automatically invoked to
resolve the problem or terminate the program in a controlled manner.
There are two kinds of exceptions in JAVA:
– Implicit (built-in) exceptions which are signals from the Java Virtual
Machine to the program indicating a violation of a semantic constraint of
the Java language. Example: an attempt to index outside the array’s
bounds will automatically throw an ArrayIndexOutOfBoundsException.
– Explicit exceptions which are intended to capture possible errors
anticipated by the program designer. Example: user input outside the
specified range. To define such an exception, a new exception class may
have to be defined.
Defining new exception classes
Version 2 of the Stack ADT implementation requires the following two exception
classes to be defined:
class StackEmptyException extends Exception {
public StackEmptyException (String message) {
System.out.println (message); } }
class StackFullException extends Exception {
public StackFullException (String message) {
System.out.println (message); } }
To throw an exception, we must create a new object of the exception’s type, i.e:
throw new StackFullException (“The stack is full.”);
The string serving as a parameter for exception constructor must be displayed by
the corresponding catch statement, i.e.
catch (StackFullException exception) {
showStatus (exception.toString());
}
The Stack ADT -- an array implementation (version 2)
class StackEmptyException extends Exception {
public StackEmptyException (String message) {
System.out.println (message);
}}
class StackFullException extends Exception {
public StackFullException (String message) {
System.out.println (message);
}}
class StackADT implements Stack {
final int MAXSIZE = 100;
private int size;
private int[] stackADT;
private int top = -1;
public void push (int number) throws StackFullException {
if (size() == size)
throw new StackFullException ("The stack is full.");
top++;
stackADT[top] = number;
}
public int pop () throws StackEmptyException {
if (empty())
throw new StackEmptyException ("The stack is empty.");
int i = stackADT[top];
top--;
return i;
}
public int ontop () throws StackEmptyException {
if (empty())
throw new StackEmptyException ("The stack is empty.");
int i = pop();
try {
push(i); }
catch (StackFullException e) {
System.out.println ("The stack is full."); }
return i;
}
............ // size, empty and full methods follow
public StackADT () {
size = MAXSIZE;
stackADT = new int[size];
}
public StackADT (int inputsize) {
size = inputsize;
stackADT = new int[size];
}
}
Example application of the Stack ADT using version 1
class StackAppl {
public static void main (String[] args) throws IOException {
Scanner scan = new Scanner(System.in);
System.out.print ("Enter stack size: ");
System.out.flush();
int size = scan.nextInt();
StackADT stack = new StackADT(size);
int i = 2;
while (!stack.full()) {
stack.push(i);
System.out.println (stack.ontop() + " is the top element.");
i = i + 2; }
System.out.println ("The current stack contains " + stack.size() + " elements.");
while (!stack.empty())
System.out.println (stack.pop() + " is removed from the stack.");
if (stack.empty())
System.out.println ("The stack is empty.");
else
System.out.println ("There are more elements on the stack.");
}
}
Example application of the Stack ADT using version 2
class StackAppl2 {
public static void main (String[] args) throws IOException {
Scanner scan = new Scanner(System.in);
System.out.print ("Enter stack size: ");
System.out.flush();
int size = scan.nextInt();
StackADTv2 stack = new StackADTv2(size);
int i = 2;
try {
// two exceptions, StackFullException and
for (int j = 1; j <= 7; j++) {
// StackEmptyException, must be watched for
stack.push(i);
System.out.println (stack.ontop() + " pushed");
i = i + 2;
}
}
catch (StackFullException e) {
System.out.println ("The stack is full."); }
catch (StackEmptyException e) {
System.out.println ("The stack is empty."); }
System.out.println ("The current stack contains " + stack.size() + " elements.")
try {
for (int j = 1; j <= 7; j++) {
System.out.println (stack.pop() + " poped");
}}
catch (StackEmptyException e) {
System.out.println ("The stack is empty.");
} } }
Download