550 likes | 673 Views
Objectives. By the end of this lecture, students should: understand iteration over arrays searching and sorting in arrays the differences in efficiency for different types of searching understand how to represent a list in an array
E N D
Objectives • By the end of this lecture, students should: • understand iteration over arrays • searching and sorting in arrays • the differences in efficiency for different types of searching • understand how to represent a list in an array • understand how to encapsulate a new datatype (here list) with its operations in a class.
13 5 19 10 7 27 17 1 Arrays as Lists • An array • stores several elements of the same type • can be thought of as a list of elements: 13 5 19 10 7 27 17 1 int a[8]
Lists • We require the following operations on lists: • adding an element • deleting an element • finding an element • getting the first element (“head”) • getting everything but the first element (“rest” or “tail”) We will now construct a class “ListInArray” that implements a list structure by using an array.
used: 1 theList ??? ??? ??? ??? ??? ??? 0 1 2 3 4 5 Unsorted List: Add • we use an array to represent the list • the size of this array dictates the maximum list length • we need to keep a counter (“used”) of how many array positions are used, ie. valid • the counter as well as the array (“theList”) will be instance variables of our “ListInArray” class Dave
Unsorted List: Add (cont) • we use an array to represent the list • the size of this array dictates the maximum list length • we need to keep a counter (“used”) of how many array positions are used, ie. valid • the counter as well as the array (“theList”) will be instance variables of our “ListInArray” class last valid index + 1 used: 2 theList Dave ??? Cary ??? ??? ??? ??? 0 1 2 3 4 5
Class Structure for Lists in Arrays • we need to store the elements (array) and the counter for used elements. public class ListInArray { private int[] theList; private int used=0; public ListInArray(int length) { // initialise instance variables theList = new int[length]; for (int i=0; i<length; i++) theList[i] = 0; } public int[] getList() { return (int[]) theList.clone(); } … // methods will follow here // define (as always): toString(), display() }
Accessor Functions and Privacy Leaks • Note that the accessor method for ”theList” does not just return the value of the instance variable. • Instead it “clones” the array. This means that it generates a complete new copy of this array and returns it. • What would happen otherwise? Consider the codeRemember that the contents of the list should only be changed via the interface of “ListInArray”. What happens here? ListInArray l = new ListInArray(5); (l.getList())[3]= 99;
Accessor Functions and Privacy Leaks • As an array variable is a reference type (like an object), the calling procedure would otherwise be able to make changes to the instance variable which we meant to be “private”. This is called a privacy leak. • Always return a clone (copy) of array-valued private instance variables. This ensures that the array cannot be changed from outside the object that “owns” this instance variable. • Cloning for arrays is a built-in function (.clone()). Cloning for objects has to be implemented by you. • Advanced Question (optional): The matter becomes truly tricky if you have arrays containing objects. What we did above is called “shallow cloning”. The technique required now is called “deep cloning”. Can you imagine what deep cloning has to do?
Adding Elements • Recall the algorithms for adding elements:if there is space left in the list { set the element at the index “used” to the new value; increment used counter; return success code (true) }else return error code (false) public boolean add(int elem) { boolean spaceLeft = (used<theList.length); if (spaceLeft) { theList[used] = elem; used ++; } return spaceLeft; }
Linear Search • Problem: determine if an element is present in an array • Method: • start at one end • look at each array element until the sought element is found • Also called sequential search
Linear Search: Algorithm and Code public boolean searchLin(int elem) { boolean found = false; int i=0; while (!found && i < used) { // stop traversing the // list as soon as // found found |= (theList[i]==elem); i++; } return found; } • isPresent (array, val, arraySize) • { • set integer count to 0 • set fboolean ound to false • while ( not found and not yet processed all array elements ) • { • if ( current array element is val ) • { • set found to true • } • increment count • } • return found • }
What does Efficiency Mean? • Algorithm: a set of instructions describing how to do a task • Program: an implementation of an algorithm • Complexity theory describes the time and space used by an algorithm The time and space requirements of an algorithm enable us to measure how efficient it is
Types of Computer Resources • Time: elapsed period from start to finish of the execution of an algorithm • Space (memory): amount of storage required by an algorithm • Hardware: physical mechanisms required for executing an algorithm
How to Measure Efficiency? • Use your watch? Use the computer clock? • Not a good idea, because: • What if you run your program on different computers? • Your program may also wait for I/O or other resources • While running a program, a computer performs many other computations • Depends on programming/coding skill
Abstract Notion of Efficiency • We are interested in the number of steps executed by an algorithm • step execution of an instruction • The running time of an algorithm is proportional to the number of steps executed by the algorithm • Running time is given as a function of the size of the input data: “Big-O Notation”
Linear Search Efficiency • What is the size of the input data? • The size of the array being searched is N • What is the time complexity of this algorithm? • Each time through the loop we perform • 3 operations (negation, comparsion, and) !found && i<used • 1 array access, 1 comparison, 1 operation (or), and 1 assignment found = ( found | (theList[i]==elem) ) • Total: 7 operations • So we execute approximately f(N)=7*N ops.
Linear Search Efficiency (cont) • Best case? • Wanted item is at the start of the list 2 (initializations) + 7 operations • Worst case? • Wanted item is not found 2 + 7N O(N) • Average case? • Average of [Wanted item is in position 1, 2, …, N ]
Big-O Notation • Big-O notation is a function of the size of the input • Example: • Input: N integers • Algorithm complexity: • Constant O(1) • Logarithmic O(log N) • Linear O(N) • n log(n) O(N log N) • Quadratic O(N2) • Cubic O(N3) • Exponential O(2N)
Calculating Complexity: Big-O Notation • Simplify and choose the highest term • Examples: 2 + 3N + 10N + 3N2 + 100 • = 3N2 + 13N + 102 O(N2) 40N + N3O(N3) 25 O(1)
Binary Search • Can we do any better than linear search? • Example: • How do you find a word in the dictionary, or a number in the phone directory? • Assume that the array is sorted and use bisection
Binary Search (cont) If ( value == middle element ) value is found else if ( value < middle element ) search left-half of list with the same method else search right-half of list with the same method
0 1 2 3 4 5 6 7 8 mid = (0 + 8) / 2 = 4 10 mid Binary Search -- Example 1 Case 1: val == a[mid] val = 10 low = 0, high = 8 a: 1 5 7 9 10 13 17 19 27 low high
new low 0 1 2 3 4 5 6 7 8 new low = mid + 1 = 5 13 13 17 17 19 19 27 27 Binary Search -- Example 2 Case 2: val > a[mid] val = 19 low = 0, high = 8 mid = (0 + 8) / 2 = 4 a: 1 5 7 9 10 low high mid
new high 0 1 2 3 4 5 6 7 8 new high = mid - 1 = 3 1 1 5 5 7 7 9 9 Binary Search -- Example 3 Case 3: val < a[mid] val = 7 low = 0, high = 8 mid = (0 + 8) / 2 = 4 a: 10 13 17 19 27 low high mid
0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7 8 8 8 a: 1 5 10 13 17 19 27 a: 1 5 7 7 9 9 10 13 17 19 27 a: 1 5 7 9 10 13 17 19 27 Binary Search -- Example 3 (cont) val = 7
Binary Search -- Algorithm and Code • isPresent (array, val, arraySize) • { • set low to first array position • set high to last array position • set found to false; • while ( not found and low < = high ) • { • set mid to half of low + high • if (array element in mid is val ) • { • set found to true • } • else if ( middle value < val ) • { • set low to mid + 1 • } • else • { • set high to mid - 1 • } • } • return found • } public boolean searchBin(int elem) { boolean found = false; int low=0, high=used-1; while (!found && low <= high) { // if not found the indices // will "cross over" int mid = (low+high)/2; if (theList[mid]==elem) found = true; else if (theList[mid] < elem) low = mid+1; else high = mid-1; } return found; }
Binary Search -- Exercise • How would you modify the program so that it returns the position of the sought item (i.e., findPosition rather than isPresent)? • How would you indicate “not found”?
Binary Search -- Exercise • Return the current index when found • Return an impossible index (eg -1) if not found. • public int findIndex(int elem) { • boolean found = false; • int low=0, high=used-1; • int mid=0; • while (!found && low <= high) { • // if not found the indexes will "cross over" • mid = (low+high)/2; • if (theList[mid]==elem) • found = true; • else if (theList[mid] < elem) low = mid+1; • else high = mid-1; • } • if (found) return mid; • else return -1; • }
Binary Search Efficiency • What is the size of the input data? • The size of the array being searched is N • What is the time complexity of this algorithm? • Each time through the loop (without finding) we perform • 2 array access • 3 comparisons • 5 arithmetic and boolean operations • 2 assignments • Total: 12 operations
Binary Search Efficiency (cont) • Best case? • item is in the middle • 3+12 operations O(1) • Worst case? • item is not found • 12 log2N operations O(log2N) • Average case? • O(log2N)
Calculating the Worst Case Complexity • After 1 bisection N/2 items • After 2 bisections N/4 = N/22 items • . . . • After i bisections N/2i =1 item • i = log2 N
Exercise Problem: Implement search over an array of objects, e.g. persons? Method: Use the “Person” class you encountered earlier. Use linear search. Search for a particular name. For binary search the array must be sorted. Assume that the “Person”s are sorted by name. You need to use the method “compareTo” in the class “String” to compare Strings lexicographically (see Java API documentation).
Notes on Searching • Linear search can be done on any (sorted or unsorted) list, but it is inefficient • Binary search • requires a list to be sorted • is more efficient • Sorting a list: later
Sorted Lists • As we have seen that we may require a list in sorted form, we’d better create an insert method that allows us maintain the sorted order of a list. • We can use the same class structure as before, we just need to insert in the right positions.
used: 0 theList ??? ??? ??? ??? ??? ??? 0 1 2 3 4 5 Empty Sorted List public class ListInArray { private int[] theList; private int used=0; …
Sorted List: Add Sorted • Case 1:List is empty • same as unsorted • Example: add sorted “Dave” used: 1 theList Dave ??? ??? ??? ??? ??? 0 1 2 3 4 5
used: 1 theList Dave ??? ??? ??? ??? ??? 0 1 2 3 4 5 Sorted List: Add Sorted • Case 2:List is not empty • find correct position • Example: add sorted “Abe”
used: 1 theList Dave ??? ??? ??? ??? 0 1 2 3 4 5 Sorted List: Add Sorted • Case 2: List is not empty • find correct position • make room by moving all items to the right • Example: add sorted “Abe”
used: 1 theList Abe Dave ??? ??? ??? ??? 0 1 2 3 4 5 Sorted List: Add Sorted • Case 2: List is not empty • find correct position • make room by moving all items to the right • put item in that position • Example: add sorted “Abe”
used:2 theList Abe Dave ??? ??? ??? ??? 0 1 2 3 4 5 Sorted List: Add Sorted • Case 2: List is not empty • find correct position • make room by moving all to the right • put item in that position • update “used” count • Example: add sorted “Abe”
used: 4 theList Abe Cary Dave Ed ??? ??? 0 1 2 3 4 5 Sorted List: Add Sorted • Case 2: List is not empty • Example: add sorted “Arnie”
used: 4 theList Abe Cary Dave Ed ??? 0 1 2 3 4 5 Sorted List: Add Sorted • Case 2: List is not empty • Example: add sorted “Arnie”
used: 5 theLIst Abe Arnie Cary Dave Ed ??? 0 1 2 3 4 5 Sorted List: Add Sorted • Case 2: List is not empty alphabetical ordering is maintained • Example: add sorted “Arnie”
used: 5 theList Abe Arnie Cary Dave Ed ??? 0 1 2 3 4 5 Sorted List: Add Sorted • Case 2: List is not empty What if the arrayis already full?
AlgorithmaddSorted boolean addSorted(elem) { set successcode = true if space is left set I to first index if list is not full { while (end of used array not reached and theList[i]<= elem) increment i; for (j from last used index down to i) shift element at index j-1 one position up insert elem in the empty spot of array update used counter } return successcode }
MethodaddSorted public boolean addSorted(int elem) { boolean spaceLeft = (used<theList.length); if (spaceLeft) { int i = 0; while(i<used && theList[i]<=elem) i++; for (int j=used; j>i; j--) theList[j] = theList[j-1]; theList[i]=elem; used++; } return spaceLeft; }
List: Delete an Element • Same for both sorted and unsorted lists • Algorithm: • find the position of the item to be deleted • linear or binary search • if found • move all items one position to the left • decrement count • Special cases: • list is empty • item not found
List: Delete an Element • - find the position of the element Example: delete “Cary” used: 5 theList Abe Arnie Cary Dave Ed ??? 0 1 2 3 4 5
List: Delete an Element • - find the position of the element • - remove the element Example: delete “Cary” used: 5 theList Abe Arnie Dave Ed ??? 0 1 2 3 4 5
List: Delete an Element • - find the position of the element • - remove the element • - shuffle the items after the deleted item to the left We don’t need to actually clear this. Just update used Example: delete “Cary” used:5 theList Abe Arnie Dave Ed Dave Ed ??? 0 1 2 3 4 5