Here is a brute force search. We are go through ALL of the array and for each value we look for a match. (If we have an unordered array this is the best search that we can do):Reversing ArraysHowever we have an ordered array, so we can do better. If we know that the array is ordered we can stop searching as soon as we get to a .compareTo() value that is too large. So let's rewrite contains():public boolean contains (String name){ for (int index = 0; index < count; index++){ if (names[index].compareTo(name)==0){ return true; } } return false; }
However we can still do better. How about eliminating half of the array for each comparison? If you start in the middle of the array each time (where each time you shink the "to search" array by half to include only the possible values) you will get to your answer much faster. Here's some examples:public boolean contains (String name){ for (int index = 0; index < count; index++){ int differance = names[index].compareTo(name) if(differance == 0){ return true; } if (differance >0){ //know that we have gone too far so now can disapoint people much faster return false; } } //if we exit loop we know the value isn't there return false; }
This is called a binary search. Each time you are shrinking your searchable array be half:a c e g h j l p q r (looking for d) //Compare d to j (must be in front of j) a c e g h //excluded: j l p q r //Compare d to e (must be in front of e) a c //excluded:e g h j l p q r //Compare d to c (must be at 0 or not in list) a //excluded:c e g h j l p q r //Compare d to a (now know not in array) c e g h j l p q r (looking for q) //Compare q to j (must be behind j) j l p q r //excluded: a c e g h //Compare q to p (must be behind p) q r //excluded: a c e g h j l p //Compare q to r (must be in front of r) q //excluded: a c e g h j l p r //Compare q to q (we found it!)
64 => 32 => 16 => 8 => 4 => 2 => 1(found it!)
so that's how many searches?So for a sorted array of N items...How many times will we need to call compareTo, in the worst case? log2(N) + 1| Rewritten | | | in powers | Power in | Number of N | of 2 | terms of N | comparisons ------+------------+-------------+------------- 64 | 2^6 | 6=log2(64) | 7 32 | 2^6 | 5=log2(32) | 6 16 | 2^6 | 4=log2(16) | 5 8 | 2^6 | 3=log2(8) | 4 4 | 2^6 | 2=log2(4) | 3 2 | 2^6 | 1=log2(2) | 2 1 | 2^6 | 0=log2(1) | 1
The code for a binary search:
public boolean binarySearch (String name){ int left = 0; int right = count-1; int pivot = left + (right-left)/2; while(right >= left) { int differance = names[pivot].compareTo(name); if (differance == 0){ return true; } if (differance > 0) { //go left //left value stays the same right = pivot - 1; //can exclued the pivot point } else { //go right //right stays same left = pivot + 1; } pivot = left + (right-left)/2; } //if exit loop then know that the searched for value isn't there return false; }
NOTE: This breaks binary search (The comparisons are now being done backwards. To correct this you would have to change the code of the binary search).Example of swapping:
So you swap until you reach middle of set. Let's write the reverse() code:have array: 1 2 3 4 5 //Swap 1 and 5 5 2 3 4 1 //Swap 2 and 4 5 4 3 2 1 //You are done since you don't need to swap 3 with itself
public void reverse(){ for (int offset = 0; offset < (count/2); offset++) { swap( offset, (count-1)-offset); } }