Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Data Structures A data structure is the building block of programming It defines how data is organized and consequently has influence on how data is allocated in a computer memory The importance of data structures for algorithm efficiency cannot be overemphasized. The efficiency of most algorithms is directly linked to the data structure choice Some algorithms are basically a data structure definition (plus the operations associated with the structure) For the same amount of data, different data structures can take more or less space in the computer memory © Ronaldo Menezes, Florida Tech Data Structures We mentioned in the previous slide the operations associated with the structure. What are these? A data structure is not passive It consists of data and operations to manipulate the data They are implementation of ADTs (Abstract Data Types) © Ronaldo Menezes, Florida Tech Linear vs. Nonlinear For a structure to be linear all of the above has to be true There is a unique first element There is a unique last element Every component has a unique predecessor (except the first) Every component has a unique successor (except the last) If at least one of the above is false, the structure is nonlinear © Ronaldo Menezes, Florida Tech Direct vs. Sequential Access In any linear data structure we have to methods of access the data stored Sequential structures are such that we can only access the Nth element we have to accessed all element preceding N. This means that all elements from 1 to N-1 will have to be accessed first. Think of how a specific music is accessed in an iPod shuffle (with the shuffle off!) Direct access structures are such that any element of the structure can be accessed directly. There is no need to access any other object besides the element required. Think CD player here. © Ronaldo Menezes, Florida Tech Elementary Data Structures Elementary Data Structures Linear Nonlinear Sequential Access Direct Access Set Homogeneous Components Heterogeneous Components General LIFO FIFO Array Record List Stack Queue Arrays One of the most common types of data structures Normally pre-defined in most programming languages Has the advantage of providing direct access to elements But also disadvantages: Fixed size Homogeneous elements Normally implemented by using contiguous allocation of memory cells This is not however required at the ADT definition level. The array implementation may give the impression of contiguousness. © Ronaldo Menezes, Florida Tech Arrays as ADTs Domain A collection of fixed number of components of the same type A set of indexes used to access the data stored in the array. There is a one-to-one relation between index and objects stored. Operations valueAt(i): Index i is used to access the value stored in the corresponding position of the array Most languages use the [ i ] as syntax instead of valueAt. store(i,v): Stores the value v into the array position i Most languages use the = operator © Ronaldo Menezes, Florida Tech Prime Testing Given a sequence of numbers from 2..N where N is given as an input, write an algorithm that finds all prime numbers between 2 and N. How do we do this? If I allow you to use an array of size N can you make use of the direct access that exist in the array to improve your solution? © Ronaldo Menezes, Florida Tech Sieve of Eratosthenes (Prime Testing) public class Sieve { public static void main (String args[]) { int n = Integer.parseInt(args[0]); boolean numbers[] = new boolean[n+1]; for (int i = 2; i <= n; i++) { numbers[i] = true; } for (int i = 2; i <= n; i++) { if (numbers[i]) { for (int j = i; j*i <= n; j++) { numbers[j*i] = false; } } } for (int i = 2; i <= n; i++) { if (numbers[i]) { System.out.println(i); } } } } © Ronaldo Menezes, Florida Tech Bernoulli Trials Named after the Swiss mathematician Jacob Bernoulli The term is used to refer to an experiment on a random process that could have 2 possible outcomes Success or failure Processes are independent Did the gambler win or loose? Is the child a boy or girl? If I flip a coin does it land heads or tails? A Bernoulli process is a series of executions of Bernoulli Trials © Ronaldo Menezes, Florida Tech Coin Flipping Simulation (simulation of Bernoulli trials) public class CoinFlippingSimulation { private static boolean heads() { return (Math.random() < 0.5); } public static void main (String args[]) { int cnt = 0, j; int n = Integer.parseInt(args[0]); int m = Integer.parseInt(args[1]); int[] result = new int[n+1]; for (int i = 0; i < m; i++) { cnt = 0; for (j = 0; j < n; j++) { if (heads()) cnt++; } result[cnt]++; } for (j = 0; j <= n; j++) { if (result[j] == 0) { System.out.print("."); } for (int i = 0; i < result[j]; i+=10) { System.out.print("*"); } System.out.println(); } } } © Ronaldo Menezes, Florida Tech Histogram of Execution 16 Flips 1000 Executions Circular Lists Circular linked lists are just a variation of a singly linked list They have the same "internal" structure (internal nodes). The difference lies on the fact that link member of the last node points to the first instead of pointing to null Circular list are useful when we're not interested on which node is the first or the last in the list In this structure the head can point to any node and it is not used to keep nodes from being lost in the list. Some problems are better described using circular lists eg. the Josephus election Algorithms for dealing with circular linked lists are simpler than for singly linked lists because we don't need to test for special cases If the last node needs to be identified, we need to test differently (from other linked lists) The node that is pointing to the same location as the head is the last one. © Ronaldo Menezes, Florida Tech Pictorial View of Circular Linked Lists head 5 12 © Ronaldo Menezes, Florida Tech 9 Josephus Election class Josephus { static class Node { int val; Node next; Node(int v) { val = v; } } public static void main(String[] args) { int N = Integer.parseInt(args[0]); int M = Integer.parseInt(args[1]); // creation of circular list Node t = new Node(1); Node x = t; for (int i = 2; i <= N; i++) { x = (x.next = new Node(i)); } x.next = t; while (x != x.next) { // finds element to eliminate for (int i = 1; i < M; i++) { x = x.next; } // eliminate element x.next = x.next.next; } System.out.println("The elected is " + x.val); } } © Ronaldo Menezes, Florida Tech Generalized Josephus Election (Take Home Quiz) Implement the “cat” version of the Josephus where members have multiple lives. In this version you should also be allowed to choose where on the list you’d like to start Later compare your implementations with the standard Josephus problem given in the previous slide The generalized solution with the number of lives being 1 should give the same solution as the standard version. Due on Monday Hand printout of program to me. © Ronaldo Menezes, Florida Tech What is a List? It is a linear structure that provides only sequential access to its elements It normally has two "special" named elements called head and tail. They point to the first and last element of the list respectively Lists differ from arrays because they don't have a fixed size but like arrays, they can only store elements of the same type A homogeneous structure A well defined list can be used as the basis for the implementation of several other data structures, such as queues and stacks. Main advantage over arrays is easy insertion and deletion of nodes When implemented using dynamic allocation © Ronaldo Menezes, Florida Tech Lists as ADTs Domain A collection elements of the same type A list cursor which enable us to walk in the list from position 1 to n Operations create(): create a new list. Should be done using constructors isEmpty() & isFull(): returns true if the list is empty and full respectively insertEnd(v) & insertBeginning(v): Insert the value v either in the end or in the beginning of the list delete(v): deletes first occurrence of a value v deleteAll(v): Delete all occurrences of v in the list reset(): Delete all elements in the list. © Ronaldo Menezes, Florida Tech Implementation via Arrays create() 0 1 2 3 4 MAX_SIZE = 8 size = 0 head = -1 tail = 0 © Ronaldo Menezes, Florida Tech 5 6 7 Implementation via Arrays insertEnd(40) 0 1 2 3 4 12 3 33 7 2 v 40 © Ronaldo Menezes, Florida Tech 5 6 7 Implementation via Arrays insertEnd(40) 0 1 2 3 4 5 12 3 33 7 2 40 if list is not full list[tail++] = v size++ © Ronaldo Menezes, Florida Tech 6 7 Implementation via Arrays insertBeginning(22) 0 1 2 3 4 5 12 3 33 7 2 40 v 22 © Ronaldo Menezes, Florida Tech 6 7 Implementation via Arrays insertBeginning(22) 0 1 2 3 4 5 6 12 3 33 7 2 40 40 v 22 © Ronaldo Menezes, Florida Tech 7 Implementation via Arrays insertBeginning(22) 0 1 2 3 4 5 6 12 3 33 7 2 2 40 v 22 © Ronaldo Menezes, Florida Tech 7 Implementation via Arrays insertBeginning(22) 0 1 2 3 4 5 6 12 3 33 7 7 2 40 v 22 © Ronaldo Menezes, Florida Tech 7 Implementation via Arrays insertBeginning(22) 0 1 2 3 4 5 6 12 3 33 33 7 2 40 v 22 © Ronaldo Menezes, Florida Tech 7 Implementation via Arrays insertBeginning(22) 0 1 2 3 4 5 6 12 3 3 33 7 2 40 v 22 © Ronaldo Menezes, Florida Tech 7 Implementation via Arrays insertBeginning(22) 0 1 2 3 4 5 6 12 12 3 33 7 2 40 v 22 © Ronaldo Menezes, Florida Tech 7 Implementation via Arrays insertBeginning(22) 0 22 1 2 3 4 5 6 12 3 33 7 2 40 if list is not full for i=(tail-1) to 0 list[i+1] = list[i] list[0] = v tail++ size++ © Ronaldo Menezes, Florida Tech 7 Implementation via Arrays delete(33) 0 22 1 2 3 4 5 6 12 3 33 7 2 40 © Ronaldo Menezes, Florida Tech 7 Implementation via Arrays delete(33) 0 22 1 2 3 4 5 6 12 3 33 7 2 40 is this 33? © Ronaldo Menezes, Florida Tech 7 Implementation via Arrays delete(33) 0 22 1 2 3 4 5 6 12 3 33 7 2 40 is this 33? © Ronaldo Menezes, Florida Tech 7 Implementation via Arrays delete(33) 0 22 1 2 3 4 5 6 12 3 33 7 2 40 is this 33? © Ronaldo Menezes, Florida Tech 7 Implementation via Arrays delete(33) 0 22 1 2 3 4 5 6 12 3 33 7 2 40 is this 33? © Ronaldo Menezes, Florida Tech 7 Implementation via Arrays delete(33) 0 22 1 2 3 4 5 6 12 3 7 7 2 40 © Ronaldo Menezes, Florida Tech 7 Implementation via Arrays delete(33) 0 22 1 2 3 4 5 6 12 3 7 2 2 40 © Ronaldo Menezes, Florida Tech 7 Implementation via Arrays delete(33) 0 22 1 2 3 4 5 6 12 3 7 2 40 40 © Ronaldo Menezes, Florida Tech 7 Implementation via Arrays delete(33) 0 22 1 2 3 4 5 12 3 7 2 40 6 if list is not empty i = head+1; while (v != list[i] and i < tail) i++; if (i < tail) for j=i to (tail-2) list[i] = list[i+1]; list[tail-1] = null; size--; tail--; © Ronaldo Menezes, Florida Tech 7 Linked Lists Another (and better) alternative to implement lists is the use of dynamic allocation (aka Linked Lists). It consists of a collection of records called nodes each containing at least one member that gives the location of the next node in the list. Note that in the array-lists discussed before, the location of the “next” node was implicit In the simplest case a node contains a data member representing the value and a link member representing the location of the successor of this node. Because we have the link member we can store nodes anywhere in memory and not necessarily contiguously. The standard pictorial view of a linked list is: head 5 12 © Ronaldo Menezes, Florida Tech 9 / Advantages and Disadvantages Advantages of Dynamic Lists (or Linked Lists) Fair use of memory Size of the structure does not need to be declared in advance Common operations (insert, delete, etc.) are cheaper Disadvantages Algorithms are more complex, harder to read and harder to debug Allocation and de-allocation of memory space impose some overhead to the performance of the algorithm © Ronaldo Menezes, Florida Tech Inserting a New Node head 5 12 / © Ronaldo Menezes, Florida Tech Inserting a New Node head 5 12 / temp 13 © Ronaldo Menezes, Florida Tech Inserting a New Node head 5 12 / temp 13 © Ronaldo Menezes, Florida Tech Inserting a New Node head 5 12 / temp 13 © Ronaldo Menezes, Florida Tech Inserting a New Node head 5 12 / 13 © Ronaldo Menezes, Florida Tech Inserting at index 2 head 13 5 12 / © Ronaldo Menezes, Florida Tech Inserting at index 2 head 13 5 12 / index © Ronaldo Menezes, Florida Tech Inserting at index 2 head 5 13 12 / index temp © Ronaldo Menezes, Florida Tech 7 Inserting at index 2 head 5 13 12 / index temp © Ronaldo Menezes, Florida Tech 7 Inserting at index 2 head 13 5 12 / 7 © Ronaldo Menezes, Florida Tech Insertion Checks When examining a list, we most often have to consider three separate cases The node is the first node of the list The node is an “interior” node The node is the last node of the list The above is the reason why some programs choose to use sentinels in their linked lists. © Ronaldo Menezes, Florida Tech Deleting element 7 head 13 5 7 12 / © Ronaldo Menezes, Florida Tech Deleting element 7 head 13 5 7 12 / current © Ronaldo Menezes, Florida Tech Deleting element 7 head 13 5 7 12 / temp current © Ronaldo Menezes, Florida Tech Deleting element 7 head 13 5 7 12 / temp current © Ronaldo Menezes, Florida Tech Deleting element 7 head 13 5 12 / temp current © Ronaldo Menezes, Florida Tech Deleting element 7 head 13 5 12 / © Ronaldo Menezes, Florida Tech Array Implementation of Linked Lists It is common to associate linked lists with dynamic data but the two concepts are independent. Arrays can be used to implement linked lists Linked Lists are very much related to the machine memory So what if we simulate what is going on in memory? The standard way to do it is to have An array of “nodes” which will simulate the memory An array of boolean which keeps track of the free © Ronaldo Menezes, Florida Tech Pictorial View public class Node { char data; int next; ... } Node[] list = new Node[100]; int head; boolean[] free = new boolean[100]; head 5 [0] [1] G [2] [3] [4] F 2 -1 [0] [1] [2] [3] FALSE TRUE FALSE TRUE [4] TRUE © Ronaldo Menezes, Florida Tech [5] P ... 0 ... [5] FALSE ...