Download presentation
Presentation is loading. Please wait.
1
1 Lecture 25 Abstract Data Types –II Overview A stack Interface in Java StackEmptyException Stack ADT(A Simple Array-Based Implementation Queue Abstract Data Type Problems with Array Implementation Dynamic Data Structures LinkedList Node Implementation Preview: Abstract Data Types III.
2
2 Lecture 25 A stack Interface in Java Because of its importance, the stack data stucture is included as a “built-in” class in the java.util package of Java. Class java.util.Stack is a structure that stores generic Java object and includes, among others, the methods push(obj), pop(),peek() equivalent to top()), size(), and empty()(equivalent to isEmpty()). Implementing an abstract data type in Java involves two steps. The first step is definition of a Java Application Programming Interface(API), or simply interface, which describes the names of the methods that the ADT supports and how they are to be declared and used. Note that this interface is very general since it specifies that objects of arbitrary, and possible heterogeneous classes can be inserted into the stack
3
3 Lecture 25 Interface Stack /** * Interface for a stack: a collection of objects * that are inserted and removed according to the * last-in first-out principle. */ public interface Stack { /** * @return number of elements in the stack. */ public int size(); /** * @return true if the stack is empty, false otherwise. */ public boolean isEmpty(); /** * @return top element in the stack. * @exception StackEmptyException if the stack is empty. */ public Object top() throws StackEmptyException ; /** * Insert an element at the top of the stack. * @param element element to be inserted. */ public void push (Object element); /** * Remove the top element from the stack. * @return element removed. * @exception StackEmptyException if the stack is empty. */ public Object pop() throws StackEmptyException; }
4
4 Lecture 25 A Stack Interface
5
5 Lecture 25 StackEmptyException Exception thrown by methods pop() and top() of the Stack interface when called on an empty Stack /** * Runtime exception thrown when one tries to perform operation top or * pop on an empty stack. */ public class StackEmptyException extends RuntimeException { public StackEmptyException(String err) { super(err); }
6
6 Lecture 25 Stack ADT(A Simple Array-Based Implementation ) Since an array’s size needs to be determined when it is created, one of the important details of our implementation is that we specify some maximum size N for our stack, say, n= 1000 elements. Our stack then consists of an N-element. A StackFullException can be raised if we try to insert a new element and the array S is full.
7
7 Lecture 25 An Array-Based Stack(algorithm)
8
8 Lecture 25 Array-based Java Implementation of the Stack interface /** * Implementation of the Stack interface using a fixed-length array. * An exception is thrown if a push operation is attempted when the size of * the stack is equal to the length of the array. */ public class ArrayStack implements Stack { /** * Default length of the array used to implement the stack. */ public static final int CAPACITY = 1000; /** * Lenght of the array used to implement the stack. */ private int capacity; /** * Array used to implement the stack. */ private Object S[]; /** * Index of the top element of the stack in the array. */ private int top = -1; /** * Initialize the stack to use an array of default length CAPACITY. */ public ArrayStack() { this(CAPACITY); } /** * Initialize the stack to use an array of given length. * * @param cap length of the array. */ public ArrayStack(int cap) { capacity = cap; S = new Object[capacity]; } /** * O(1) time. */ public int size() { return (top + 1); }
9
9 Lecture 25 Array-based Java Implementation of the Stack interface /** * O(1) time. */ public boolean isEmpty() { return (top < 0); } /** * O(1) time. * @exception StackFullException if the array is full. */ public void push(Object obj) throws StackFullException { if (size() == capacity) throw new StackFullException("Stack overflow."); S[++top] = obj; } /** * O(1) time. */ public Object top() throws StackEmptyException { if (isEmpty()) throw new StackEmptyException("Stack is empty."); return S[top]; } /** * O(1) time. */ public Object pop() throws StackEmptyException { Object elem; if (isEmpty()) throw new StackEmptyException("Stack is Empty."); elem = S[top]; S[top--] = null; // dereference S[top] for garbage collection. return elem; }
10
10 Lecture 25 Casting with a Generic Stack. Example method that reverse elements One of the strong points of our realization of the stack ADT by means of a Java class that implements the Stack interface is that we can store generic objects in the stack, each belonging to an arbitrary class. An ArrayStack in the previous slide can store Integer objects, Student objects or any object. When we retrieve an object from the stack(with either the top or pop method) we always get back a reference of type Object, no matter what the specific class of the object is. Thus in order to use the retrieved element as an instance of the specific class it really belongs to, we must perform a cast, which forces the object to be viewed as a member of a specific class rather than a more general superclass Object. public static Integer[] reverse(Integer[] a) { ArrayStack S = new ArrayStack(a.length); Integer[] b = new Integer[a.length]; for (int i=0; i < a.length; i++) S.push(a[i]); for (int i=0; i < a.length; i++) b[i] = (Integer) (S.pop()); return b; } //Casting is performed to force the object returned by pop to viewed as an Integer object
11
11 Lecture 25 Queue Abstract Data Type r (r+1)mod N Using array Q in a circular fashion:”Wrapped around” Normal configuration
12
12 Lecture 25 A Queue Interface public interface Queue { /** * @return number of elements in the queue. */ public int size(); /** * @return true if the queue is empty, false otherwise. */ public boolean isEmpty(); /** * Inspect the element at the front of the queue. * * @return element at the front of the queue. * @exception QueueEmptyException if the queue is empty. */ public Object front() throws QueueEmptyException ; /** * Insert an element at the rear of the queue. * * @param element new element to be inserted. */ public void enqueue (Object element); /** * Remove the element at the front of the queue. * * @return element removed. * @exception QueueEmptyException if the queue is empty. */ public Object dequeue() throws QueueEmptyException ; }
13
13 Lecture 25 Problems with Array Implementation when implementing data structures using arrays, we need to be careful with the size of array chosen: too small : unsuitable for the application. too big : wasteful of space. performance : can be an issue for certain operations because of need to move array elements around. An alternative is to use a dynamic list structure which is able to grow and shrink as the application demands: no estimate of size is required upfront. Does not suffer from performance problems outlined earlier with an array implementation. These structures are also known as linked lists
14
14 Lecture 25 Inserting/Deleting an Element( Problems with Array) 1330 45 15 Insert 5 here 0 1 2 3 4 n-1 13 15 45 Move elements from position 1 up one place 305 13 5 4515 Delete this 0 1 2 3 4 n-1 1545 Move elements from position 3 down one place 305
15
15 Lecture 25 Dynamic Data Structures So far we have studied fixed-size data structures such as single-subscripted arrays Here we are introducing dynamic data structures that grow and shrink during execution. A linked list is based on the concept of a self- referential object -- an object that refers to an object of the same class. Self-referential class objects can be linked together to form useful data structures such as lists, stacks, queues, and treesSelf-referential class objects can be linked together to form useful data structures such as lists, stacks, queues, and trees
16
16 Lecture 25 The Linked List Data Structure l A linked list is based on the concept of a self-referential object -- an object that refers to an object of the same class. public class Node { private String name; private Node next; } A link to another Node object. Data LinkReferenceNull reference Nuri OmerSami Node
17
17 Lecture 25 Dynamic Linked List Structures Each node consists of a data element and reference which points to the next node in the list. The last node reference is initialised to a null value and this is used to terminate the list. Implementation Issues If a header reference is used to point to the 1st list node: insertion and deleting first element requires the header to be updated to reflect the changes to the start of the list. deleting in general requires that we keep track of the node in front of the one to be deleted so that the links can be updated. header elementnext List Nodes elementnextelementnext
18
18 Lecture 25 Solution - Using a Dummy Header Node Using a dummy header node solves the problems outlined earlier with a header reference. To solve deletion problems we need to provide a findPrevious method which returns a reference to the predecessor of the node we wish to delete. If we delete the first node then findPrevious will return the header node whose next reference can be updated. Inserting a new first node only requires that the header next reference be updated to point to the new first node. dummy header elementnext List Nodes elementnextelementnext
19
19 Lecture 25 Singly-linked list The singly-linked list is the most basic of all the linked data structures. A singly-linked list is simply a sequence of dynamically allocated objects, each of which refers to its successor in the list. Despite this obvious simplicity, there are myriad implementation variations. The figure below shows several of the most common singly-linked list variants. head (a) tail (d) head sentinel (c) head tail (b)
20
20 Lecture 25 Linked List (Cont’d) The basic singly-linked list is indicated in the above figure by (a). Each element of the list refers to its successor and the last element contains the null reference. One variable, labeled head, is used to keep track of the list. The basic singly-linked list is inefficient in those cases when we wish to add elements to both ends of the list. While it is easy to add elements at the head of the list, to add elements at the other end we need to locate the last element. If the basic basic singly-linked list is used, the entire list needs to be traversed in order to find its tail. The list labeled (b) shows a way in which to make adding elements to the tail of a list more efficient. The solution uses a second variable, tail, which refers to the last element of the list. Of course, this time efficiency comes at the cost of the additional space used to store the variable tail. head (a) head tail (b)
21
21 Lecture 25 Linked List (Cont’d) The singly-linked list labeled (c) illustrates two common programming tricks. There is an extra element at the head of the list called a sentinel. This element is never used to hold data and it is always present. The principal advantage of using a sentinel is that it simplifies the programming of certain operations. For example, since there is always a sentinel standing guard, we never need to modify the head variable. Of course, the disadvantage of a sentinel such as shown is that extra space is required, and the sentinel needs to be created when the list is initialized. The list (c) is also a circular list. Instead of using a null reference to demarcate the end of the list, the last element of the list refers to the sentinel. The advantage of this programming trick is that insertion at the head of the list, insertion at the tail of the list, and insertion at an arbitrary position of the list are all identical operations. head sentinel (c)
22
22 Lecture 25 Linked List (Cont’d) Of course, it is also possible to make a circular, singly-linked list that does not use a sentinel. The list labeled (d) shows a variation in which a single variable is used to keep track of the list, but this time the variable, tail, refers to the last element of the list. Since the list is circular in this case, the first element follows the last element of the list. Therefore, it is relatively simple to insert both at the head and at the tail of this list. This variation minimizes the storage required, at the expense of a little extra time for certain operations. tail (d) (e) Doubly Linked List
23
23 Lecture 25 LinkedList Node Implementation The structure is self-referential in nature as the reference which is part of the class is also capable of referring to a ListNode (i.e. itself). A node class should also provide an appropriate set of constructors and node interface methods. public class Node { private Object element; // Object type stored in this node private Node next; // reference to another node // class methods go here } If an abstract data type is to be truly abstract then the type of the element that it is used to manage should be irrelevant. We will therefore store instances of the base Java Object type in our node which is represented by a Java class as follows. click here on this link Linked List Linked List
Similar presentations
© 2024 SlidePlayer.com Inc.
All rights reserved.