maze exit finder cont choosing maze data structures
play

Maze exit finder (cont.) Choosing maze data structures How to - PDF document

Maze exit finder (cont.) Choosing maze data structures How to represent a maze square? Solution must lead to smaller problems boolean find_exit(int x, int y) /* 2 nd try */ Okay, a class, but what data are stored? { if ( we have been


  1. Maze exit finder (cont.) Choosing maze data structures � How to represent a maze square? � Solution must lead to smaller problems boolean find_exit(int x, int y) /* 2 nd try */ – Okay, a class, but what data are stored? { if ( we have been here before ) � Ways to know if exit or not, if has been visited yet or not return false; /* don’t try same spot again */ � Maybe ways to know about neighboring squares if ( x,y is an exit ) – How about some helper methods? return true; /* success! */ � e.g., isExit(), isMarked(), hasNeighbor(direction), … /* rest as before */ � How to represent the whole maze? � So need a way to remember where we’ve been – Suggest: array of references to maze squares – e.g., mark square upon entering find_exit – Any other ways? – Q: is it ever necessary to remove the mark? Towers of Hanoi (demo) Decimal (value) to binary (string) /** � Problem: move n disks from peg a to peg c, using * Returns a String representation of the binary equivalent peg b to hold disks temporarily; keep small on top * of a specified integer. The worstTime(n) is O(log n). * @param n – an int in decimal notation. � Recursive solution: method with params n , a , b , c * @return the binary equivalent of n, as a String – Base case: just one disk – trivial: * @throws IllegalArgumentException, if n is less than 0 */ // (From Collins text’s instructor resources) � If n is 1, move 1 disk from a to c public static String getBinary (int n) { – General case: assume a method that can move a tower if (n < 0) throw new IllegalArgumentException( ); of height n-1. This method!!! � Move top n-1 disks from a to b , using c for holding purposes if (n <= 1) return Integer.toString (n); � Move the bottom disk from a to c � Move all n-1 disks on b to c , using a for holding purposes return getBinary (n / 2) + Integer.toString (n % 2); } � Iterative solution much more difficult in this case Demo Eliminating recursion Queues Rear Front � Can always simulate recursion by explicit stack – Use iteration instead of recursion last enqueued 1st enqueued � Instead of recursive call: push key values onto stack last dequeued 1st dequeued – e.g., maze finder – push coordinates (x, y) � Instead of return: pop values from stack – e.g., back to square (x, y) in maze finder � FIFO data structure – First In, First Out � Sometimes an easy non-recursive translation � Typical operations similar to stacks without a stack – especially if “tail recursion” – enqueue (an item at rear of queue) – e.g, factorial, fibonacci, ruler tick marks, … – dequeue (item at front of queue) – Much harder for maze and Hanoi examples – peek (at front item) – isEmpty , isFull , size , clear 1

  2. Some queue applications Applying a queue – palindrome � Many operating system applications � Palindrome - same forward and backward – Time-sharing systems rely on process queues – e.g., Abba, and “Able was I ere I saw Elba.” � Often separate queues for high priority jobs that take little � Lots of ways to solve, including recursive time, and low priority jobs that require more time � Can use a queue and a stack together – Printer queues and spoolers � Printer has its own queue with bounded capacity – Fill a queue and a stack with copies of letters (only) � Spoolers queue up print jobs on disk, waiting for print queue – Then empty both together, verifying equality – Buffers – coordinate processes with varying speeds � Reminder – we’re using an abstraction � Simulation experiments – We still don’t know how queues are implemented!!! – Models of queues at traffic signals, in banks, etc., To use them, it does not matter! used to “see what happens” under various conditions – Abstraction is Good! Queue interface Implementing queues � Easy to do with a list (e.g., ArrayList): � e.g., java.util.Queue: public interface Queue<E> extends Collection<E> { – Mostly same as stack implementation boolean offer(E o); // enqueue – Enqueue – add to end – list.add(item); E poll(); // dequeue (null if empty) – Then to dequeue and peek: refer to first item E remove(); // dequeue (exception if empty) � e.g., to dequeue – list.remove(0); E peek(); // peek (null if empty) � Array implementation is trickier: E element(); // peek (exception if empty) – Must keep track of front and rear indices } – Increment front/rear using modulus arithmetic � All Known Implementing Classes: � Indices cycle past last index to first again – idea is to reuse – AbstractQueue, ArrayBlockingQueue, ConcurrentLinkedQueue, the beginning of the array after dequeues DelayQueue, LinkedBlockingQueue, LinkedList, PriorityBlockingQueue, PriorityQueue, SynchronousQueue See demos in ~mikec/cs20/demo03/queue/ at CSIL Queue operation complexity What are iterators? � Implementing a queue with an array � Objects for iterating over elements of structure – enqueue(object) – add to end and increment tail index � e.g., java.util.Iterator: � O(1) if array is not full; otherwise O(n) to resize/copy interface Iterator<E> { – dequeue() – remove front and increment front index boolean hasNext(); // true if more objects � O(1) – does not depend on size of queue E next(); // return object and increment � Implementing with single-linked list // throws NoSuchElementException if !hasNext() void remove(); // optional – and potentially dangerous – enqueue(object) – add a last item // may throw UnsupportedOperationException � O(n) – for single-linked list with just a first pointer } � But O(1) if also have a pointer to last element – an easy fix � Handy to implement as inner class of structure – dequeue() – remove first item – Has reference to all data structure fields/methods � O(1) – point first at first.next – not affected by n size – Could be anonymous/local to getIterator method – Why not enqueue first and dequeue last? 2

  3. Why iterators? Implementing linked lists � Provide ability to traverse list (or other structure) � e.g., a method to insert a new second node – imagine list now is (DUS → ORD → SAN) , without direct access to nodes want (DUS → BRU → ORD → SAN) � Easy to use – e.g., print list with while loop: or now (DUS) , want (DUS → BRU) Iterator it = list.getIterator(); while (it.hasNext()) or now () , want (BRU) print(it.next()); – Any other special cases? � Even shorter with a for loop: � A strategy: for(Iterator it=list.getIterator(); it.hasNext();) print(it.next()); // the increment step happens here create new node to hold BRU – call it n; – And simpler with enhanced for loop: if empty list – set first to n; return; else set n.next to first.next; for ( DataType d : list) print(d); set first.next to n; return; Code to insert new 2 nd node Searching for a node � Assume instance variable for first node: � Idea: return reference to the node that contains ListNode first; // refers to first node or null if list is empty particular info , or return null if the info is not in � So use that fact to write “is empty” method: boolean isEmpty() { return first == null; } the list (Note: probably a private method – returns node reference) � Then easy to code insert 2 nd node method: � Strategy: void insertNewSecondNode(Object data){ declare local node reference - call it n; ListNode n = new ListNode(); // null data and next n.data = data; point n at first node in list; if (isEmpty()) first = n; // leave next null while (n points to non-null node) { else { if (n’s referent has the info) n.next = first.next; return n; first.next = n; } else advance n to n.next; } } return null if get this far; List traversal without iterators � Search strategy typifies list-hopping activity: start by referencing first node; process that node; change reference to that node’s next link; keep going until success (e.g., found info), or until end (i.e., reference is null); – Same idea works for lots of list operations � e.g., print list – immediately applicable � To append (add last), first must link-hop to last node � To remove a node, must link-hop to node that precedes it � But also usually consider potential special cases – e.g., first node, last node, empty list, just one node, … 3

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend