Data Structures A data structure is a particular way of organizing data in a computer 16. Dynamic Data Structures so that it can be used efficiently Linked lists, Abstract data types stack, queue 446 447 Motivation: Stack Examples using a Stack Browsing Websites (back button) Undo function in a text-editor Calculator (using Suffix-notation) 2 * 5 + 3 3 5 2 * + = 3 + (5 * 2) = 13 Suitable for introduction in a lecture like this 448 449
Stack Operations ( push, pop, top, empty ) We Need a new Kind of Container Up to this point: container = Array ( T[] ) 4 3 3 3 1 Contiguous area of memory, random access (to i th element) 5 5 5 5 5 push(4) pop() pop() push(1) Simulation of a stack with an array? 1 1 1 1 1 No, at some time the array will become “full”. 2 2 2 2 2 3 3 top 5 5 top() → 3 empty() → false Goal: we implement a stack class 1 1 Question: how do we create 1 5 6 3 8 9 3 3 8 9 3 2 2 space on the stack when push is called? not possible to execute push(3) here! 450 451 Arrays are no All-Rounders... Arrays are no All-Rounders... It is expensive to insert or delete elements “in the middle ”. It is expensive to insert or delete elements “in the middle ”. 1 5 6 3 8 9 3 3 8 9 1 5 6 3 8 8 9 3 3 8 9 8 If we want to insert, If we want to remove this el- we have to move ev- ement, we have to move ev- erything to the right erything to the right. (if at all there is enough space!) 452 453
The new Container: Linked List Linked List: Zoom ListNode No contiguous area of memory and no random 1 5 6 null access Each element “knows” its successor next (type ListNode ) value (type int ) Insertion and deletion of arbitrary elements is class ListNode { simple, even at the beginning of the list int value; ⇒ A stack can be implemented as linked list ListNode next; ListNode (int value, ListNode next){ this .value = value; 1 5 6 3 8 8 9 reference this .next = next; } } 454 455 Abstract Data Types Stack = Reference to Top Element A stack is an abstract data type (ADT) with operations Stack s.push(x) : Puts element x on the stack s . 1 5 6 null top_node s.pop() : Removes and returns top most element of s or null (or error message) public class Stack { s.top() : Returns top most element of s or null (or error private ListNode top_node; message). public void push (int value) {...} s.empty() : Returns true if stack is empty, false otherwise. public int pop() {...} public int top() {...} new Stack() : Returns an empty stack. public boolean empty {...} }; 456 457
Implementation push Implementation push in Java public class Stack{ private ListNode top_node; x n − 1 top x n x 1 null ... public void push (int value){ x top_node = new ListNode (value, top_node); } push(x) : } 1 Create new list element with x and pointer to the value of top . push(4); 2 Assign the node with x to top . top_node 4 1 5 6 458 459 Implementation empty in Java Implementation pop public class Stack{ x n − 1 top x n x 1 null private ListNode top_node; ... r public boolean empty(){ s. pop () : return top_node == null; 1 If top=null , then return null , or emit error message } } 2 otherwise memorize pointer p of top in auxiliary variable r . 3 Set top to p.next and return r 460 461
Implementation pop in Java Another Example: Sorted Linked List public int pop() { assert (!empty()); Required Functionality: ListNode p = top_node; (Sorted) Output top_node = top_node.next; Add a value return p.value; } (Search for a value) Remove a value top_node p 1 5 6 462 463 Goal ListNode class ListNode{ public class SortedList{ int value; ListNode head = null; ListNode next; // insert value in a sorted way ListNode (int value, ListNode next){ public void insert(int value){ ... } this.value = value; this.next = next; // remove value if in list, return if value was found in list } public boolean remove(int value){ ... } } // output list values element by element 3 7 13 22 null public void output(){ ... } } n unreachable from n 464 465
Invariants output public class SortedList{ 3 7 13 22 ListNode head = null; null ... // output list values element by element, starting from head n public void output(){ ListNode n = head; For a reference n to a node in a sorted list it holds that while (n != null){ Out.print(n.value + " − > "); either n = null , n = n.next; or n.next = null , } Out.println("NIL"); or n.next � = null and n.value ≤ n.next.value . } } 466 467 Invariants: Insertion of x Insertion // insert value in a sorted way (sorted increasingly by value) public void insert(int value){ (a) List is empty or if (head == null || value <= head.value){ // (a) or (b) head = new ListNode(value, head); (b) x ≤ n.value for all nodes n } (c) x > n.value for all nodes n else { // (c), (d) (d) There is a node n with successor m , such that ListNode n = head; ListNode prev = null; x > n.value and x ≤ m.value while (n != null && value > n.value){ prev = n; n = n.next; Development of the following code live in the lecture } prev.next = new ListNode(value, n); } } 468 469
Combine Invariants: Deletion of x // insert value in a sorted way (sorted increasingly by value) public void insert(int value){ ListNode n = head; ListNode prev = null; while (n != null && value > n.value){ (a) x is not contained prev = n; (b) x is the first element (head) n = n.next; } (c) x has a predecessor if (prev == null){ head = new ListNode(value, n); } else { prev.setNext(new ListNode(value,n)); } } 470 471 Removal Queue (FIFO) public boolean remove(int value){ ListNode n = head; A queue is an ADT with the following operations ListNode prev = null; while (n != null && value != n.value) { q.enqueue(x) : adds x to the tail (=end) of the queue q . prev = n; n = n.next; } q.dequeue() : removes x from the head of the queue and returns if (n == null) { // (a) x , null (or error message) otherwise return false; q.empty() : return true if the queue is empty, otherwise false } else if (prev == null){ // (b) head = head.next; F irst I n F irst O ut: Elements inserted first will be extracted first. } else { // (c) (implementation in the exercises) prev.setNext(n.next); } return true; } 472 473
Recommend
More recommend