1 / 68

Elementary Data Structures

Elementary Data Structures. CS 105. Elementary Data Structures. Stack container of elements that are inserted and removed last-in first-out (LIFO) Queue container of elements that are inserted and removed first-in first-out (FIFO) Deque (double-ended queue)

kennethbell
Download Presentation

Elementary Data Structures

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Elementary Data Structures CS 105

  2. Elementary Data Structures • Stack • container of elements that are inserted and removed last-in first-out (LIFO) • Queue • container of elements that are inserted and removed first-in first-out (FIFO) • Deque (double-ended queue) • container of elements that allows insertion and removal from either end

  3. Stack • Last-in, First-out (LIFO) structure • Operations • push: add element into the stack • pop: remove & return topmost element • top: return topmost element • isEmpty: check if the stack has no elements • size: return number of elements in the stack • Sample uses • “Back” button of a browser, “Undo” operation, function/method calls

  4. Stack Interface public interface Stack { public int size(); public boolean isEmpty(); public void push( Object o ); public Object top() throws EmptyStackException; public Object pop() throws EmptyStackException; } public class EmptyStackException extends RuntimeException { }

  5. Array Implementation public class ArrayStack implements Stack { private int top = -1; private Object S[]; ... } top 3 S ... x z y w

  6. Array Implementation Details • An array of objects stores the elements • An integer field points to the topmost element • Value of top is –1 when the stack is empty • A constant indicates the size/capacity of the array • Throw a StackFullException when a push is attempted on a full array

  7. ArrayStack class public class ArrayStack implements Stack { public static final int CAPACITY = 1000; private Object S[]; private int top; public ArrayStack() { S = new Object[CAPACITY]; top = -1; } public boolean isEmpty() { return (top < 0); } … }

  8. ArrayStack class continued public class ArrayStack implements Stack { … public int size() { return (top + 1); } public void push(Object obj) throws FullStackException { if (size() == CAPACITY) throw new FullStackException(); S[++top] = obj; } … } public class FullStackException extends RuntimeException { }

  9. ArrayStack class continued public class ArrayStack implements Stack { … public Object top() throws EmptyStackException { if (isEmpty()) throw new EmptyStackException(); return S[top]; } public Object pop() throws EmptyStackException { if (isEmpty()) throw new EmptyStackException(); return S[top--]; } … }

  10. Garbage collection • After a pop() operation, array still contains reference to popped element • Succeeding push() operations will override such references but it is not certain whether pushes will occur after the pops • Better to set the reference to null so that the object is garbage-collected when no longer in use

  11. Improved pop() method public class ArrayStack implements Stack { … public Object pop() throws EmptyStackException { Object elem; if (isEmpty()) throw new EmptyStackException(); elem = S[top]; S[top--] = null; // dereference S[top] for garbage collection. return elem; } … }

  12. Using the Stack Stack s1 = new ArrayStack(); String temp; s1.push( "easy" ); s1.push( "this" ); temp = (String) s1.pop(); System.out.print( temp ); s1.push( "is" ); s1.push( "class" ); while ( !s1.isEmpty() ) { temp = (String) s1.pop(); System.out.print( " "+ temp ); } System.out.println(); OK because Strings are Objects Cast object to String

  13. Stack of ints Stack s2 = new ArrayStack(); s2.push( 5 ); s2.push( 2 ); s2.push( 3 ); int num = (Integer) s2.pop(); System.out.println( num ); Allowed in Java 1.5 because primitive type values are“auto-boxed” Cast object to Integer type (not int) Note: In previous Java versions, s2.push( new Integer( 2 ) ); num = ( (Integer) s2.pop() ).intValue();

  14. Time Complexity Analysis • push() : O(1) • pop() : O(1) • isEmpty() : O(1) • size() : O(1) • top(): O(1)

  15. Array Implementation Alternative • Make top variable point to next available array position instead of actual topmost element • top = 0 when empty • top represents size top 4 S ... x z y w

  16. Problems with ArrayStack • CAPACITY needs to be specified • Consequences • stack may fill up (when size() == MAX ) • memory is wasted if actual stack consumption is way below maximum • Need a more “dynamic” implementation

  17. Linked List Implementation top null y w z A stack as a sequence of nodes

  18. The Node class public class Node { private Object element; private Node next; public Node( Object e, Node n ) { element = e; next = n; } public Object getElement() … public Node getNext() … public void setElement( Object newElem ) … public void setNext( Node newNext ) … } y

  19. Linked List Implementation • Stack is represented by a Node reference (called top) • This reference is null when stack is empty • Top refers to the top element only but links in each node keep the elements together • An integer field represents the number of elements in the stack

  20. NodeStack class public class NodeStack implements Stack { private Node top; private int size; public NodeStack() { top = null; size = 0; } public boolean isEmpty() { return (top == null); } … }

  21. NodeStack class continued public class NodeStack implements Stack { … public int size() { return size; } public void push( Object obj ) { Node v = new Node( obj, top ); top = v; size++; } … }

  22. Push operation top size 3 null y w z

  23. Push operation top size 3 null x y w z Create node

  24. Push operation top size 4 null x y w z Update top and size

  25. NodeStack class continued public class NodeStack implements Stack { … public Object top() throws EmptyStackException { if ( isEmpty() ) throw new EmptyStackException(); return top.getElement(); } public Object pop() throws EmptyStackException { if ( isEmpty() ) throw new EmptyStackException(); Object temp = top.getElement(); top = top.getNext(); size--; return temp; } … }

  26. Pop operation top size 4 null x y w z

  27. Pop operation top size 4 null x y w z temp Get top element

  28. Pop operation top size 3 null x y w z temp Update top and size

  29. Pop operation top size 3 null x y w z temp Node automatically disposed

  30. Pop operation top size 3 null x y w z Return element

  31. Using the NodeStack Stack s2 = new NodeStack(); s2.push( 5 ); s2.push( 2 ); s2.push( 3 ); int num = (Integer) s2.pop(); System.out.println( num ); Only this line changed

  32. Time Complexity Analysis • push() : O(1) • pop() : O(1) • isEmpty() : O(1) • size() : O(1) • top(): O(1)

  33. ArrayStack versus NodeStack • NodeStack uses only the memory that it needs at any given time • NodeStack has no size limit(just the system’s memory) – FullStackException not thrown • ArrayStack’s implementation is simpler • Which implementation is more efficient?

  34. Managing Multiple Implementations • Note that we now have two implementations of a Stack: public class ArrayStack implements Stack { … } public class NodeStack implements Stack { … } • Consider what code needs to be changed if we shift between implementations • It would be preferable if the code that uses the stack does not need to be updated

  35. A StackFactory Class • Use a separate class that produces Stack objects public class StackFactory { public static Stack createStack() { return new ArrayStack(); // or return new NodeStack(); } } • Advantage: • if you want to change your implementation, you just need to change StackFactory • you don’t need to change all calls to new ArrayStack in all your code!

  36. Using a StackFactory Stack s2 = StackFactory.createStack(); s2.push( 5 ); s2.push( 2 ); s2.push( 3 ); int num = (Integer) s2.pop(); System.out.println( num ); this line need not be changed even if the stack implementation changes

  37. Queue • First-in, First-out (FIFO) structure • Operations • enqueue: insert element at rear • dequeue: remove & return front element • front: return front element • isEmpty: check if the queue has no elements • size: return number of elements in the queue • Sample use • handling requests and reservations

  38. The Queue Interface public interface Queue { public int size(); public boolean isEmpty(); public void enqueue( Object o ); public Object front() throws EmptyQueueException; public Object dequeue() throws EmptyQueueException; } public class EmptyQueueException extends RuntimeException { }

  39. Array Implementation Possibilities • On enqueue, place element in the next available slot; on dequeue, remove element at position 0 and move all other elements to the left • Dequeue takes O(n) time • Have integer pointers to front and rear, increment rear on enqueue, increment front on dequeue, so that both operations are O(1)

  40. Array Implementation of a Queue • An Object array and two integers • front: index of first element in queue • rear: index of first FREE element in queue rear front 4 0 ...

  41. ArrayQueue public class ArrayQueue implements Queue { public static final int CAPACITY = 1000; private Object s[]; private int front, rear; public ArrayQueue() { s = new Object[CAPACITY]; front = rear = 0; } ... }

  42. isEmpty and Enqueue public class ArrayQueue implements Queue { ... public boolean isEmpty() { return ( front == rear ); } public void enqueue( Object o ) throws FullQueueException { if ( rear == CAPACITY ) throw new FullQueueException(); s[rear++] = o; } ... } public class FullQueueException extends RuntimeException { }

  43. Enqueue operation front rear 0 3 ...

  44. Enqueue operation front rear 0 4 ... Enqueued object

  45. Dequeue public class ArrayQueue implements Queue { ... public Object dequeue() throws EmptyQueueException { if ( isEmpty() ) throw new EmptyQueueException(); return s[front++]; } … }

  46. Dequeue operation front rear 0 4 ...

  47. Dequeue operation front rear 1 4 ... Return this object

  48. Dequeue operation Remember to set reference in array to null front rear 1 4 ... null

  49. Dequeue with Garbage Collection public class ArrayQueue implements Queue { ... public Object dequeue() throws EmptyQueueException { if ( isEmpty() ) throw new EmptyQueueException(); Object data = s[front]; s[front] = null; front++; return data; } }

  50. Circular Array • Suppose many enqueue operations followed by many dequeue operations • Result: rear approaches CAPACITY but the queue is not really full • Solution: Circular Array • allow rear (and front) to “wrap around” the array (if rear = CAPACITY-1, incrementing rear means resetting it to 0)

More Related