Difference between revisions of "Searching Arrays"

From CompSciWiki
Jump to: navigation, search
(Linear Search)
m (Added to Linear Search Section)
 
(34 intermediate revisions by 5 users not shown)
Line 1: Line 1:
{{Template:1010Topic|Chapter_TOC=[[Selection Search Algorithm]]|Introduction=Now that we have learned how to create an array, what can we do with it?  One common application involves searching the array for a particular value.
+
{{Template:1010Topic
There are a number of approaches to searching array, some more efficient than othersTwo approaches are discussed here: 1. a linear search is the easiest search algorithm to implement, but is not very efficient; 2. a binary search can be implemented only on a sorted array, but it is far more efficient than a linear search. <br><br>
+
|Chapter_TOC=[[More With Arrays]] > [[Searching Arrays]]
This section will explain what these two search algorithms are, and how to implement them. 
+
|Previous=[[Arrays of Strings]]
|Overview=After completing this section, you can...<br>
+
|Next=[[Sorting Arrays]]
1) Apply the linear search algorithm to search for an element in any array.<br>
+
|Body=
2) Apply the binary search algorthim to efficiently search for an element in a sorted array.<br>}}
+
 
 +
 
 +
==Introduction==
 +
We learned how to create arrays and you should know that an Array is a type of list that can contain one type of object. There will be situations where you will be a need to search for a particular value in an array. Today there are many algorithms to solve this problemThese algorithms have different inefficiencies which are measured as a "time complexity". In this Chapter we are going to discuss two search algorithms; Linear Search and Binary Search. Linear search is a brute force approach and Binary Search utilizes the middle index as a lower or upper bound for its search.
  
 
==Linear Search==
 
==Linear Search==
A [[#linear search]] can be used to locate a value in an array.  A linear search checks each element one after another for a match to our search value until one of two things happens: 1) our search value has been found, or 2) we have reached the end of the array (in other words, we have not found the value.)<br><br>
 
  
'''Example''': find "McAdams" in the telephone book.<br>
+
A [[Glossary#linear search|linear search]] can be used to locate a value in an array.  A linear search checks each element one after another (from left to right or right to left) for a match to our search value until one of two things happens:
Using a linear search, the algorithm would open the phone book to page 1.  On page 1, we would check every name checking if it matches "McAdams".  If "McAdams" is not on the first page, we would flip to the second page, and again, check every name for a match to "McAdams".  We would continue this until eventually we have found the "McAdams" entry in the phone book, or there was no match.<br><br>
+
<ul>
 +
<li>our search value has been found</li>
 +
<li>we have reached the end of the array (in other words, we have not found the value.)</li>
 +
</ul>
 +
 +
 
 +
'''Example''': Find "McAdams" in the telephone book.
 +
 
 +
Using a linear search, the algorithm would open the phone book to page 1.  On page 1, we would check every name checking if it matches "McAdams".  If "McAdams" is not on the first page, we would flip to the second page, and again, check every name for a match to "McAdams".  We would continue this until eventually we have found the "McAdams" entry in the phone book, or there was no match.
 +
 
 +
 
  
 
Here is the algorithm for completing a linear search:
 
Here is the algorithm for completing a linear search:
<pre>
+
 
 +
{{CodeBlock
 +
|Code=
 +
 
 
public static int linearSearch (int[] list, int searchValue)
 
public static int linearSearch (int[] list, int searchValue)
 
{
 
{
Line 21: Line 36:
 
result = -1;  //return -1 if searchValue is not found
 
result = -1;  //return -1 if searchValue is not found
  
for (counter=0; result == -1 && counter<list.length; counter++)
+
for (counter=0; result == -1 && counter<list.length; counter++)   //loop until searchValue is found or the array is out of bounds.
{//loop until searchValue is found or the array is out of bounds.
+
{
 
+
if (list[counter] == searchValue)   //found searchValue!  end loop.
if (list[counter] == searchValue)
+
{
{//found searchValue!  end loop.
+
 
result = counter;
 
result = counter;
 
}
 
}
Line 31: Line 45:
 
return result;
 
return result;
 
}//linearSearch()
 
}//linearSearch()
</pre>
+
 
 +
}}
  
 
Our linear search algorithm can be one step more efficient if our array is sorted in ascending order.  Here is an example of an unsorted array, and that same array after being sorted.  (We do not need to worry about sorting at this point, just imagine the array is sorted for you.)
 
Our linear search algorithm can be one step more efficient if our array is sorted in ascending order.  Here is an example of an unsorted array, and that same array after being sorted.  (We do not need to worry about sorting at this point, just imagine the array is sorted for you.)
  
<pre>
 
Unsorted array:      Sorted array:
 
|10|30|60|40|20|    |10|20|30|40|60|
 
</pre>
 
  
Using the sorted array above, if we were searching for the value "25", we would know after checking element 0 ("10"), element 1 ("20"), and then element 2 ("30"), that we will not find the value "25" since every element after element 2 will be greater than or equal to "30".<br><br>
+
{{OutputBlock
 +
|Code=
 +
 
 +
Unsorted array:                             
 +
 
 +
{{!}}10{{!}}30{{!}}60{{!}}40{{!}}20{{!}}   
 +
 
 +
Sorted array:
 +
 
 +
{{!}}10{{!}}20{{!}}30{{!}}40{{!}}60{{!}}
 +
 
 +
}}
 +
 
 +
Using the sorted array above, if we were searching for the value "25", we would know after checking element 0 ("10"), element 1 ("20"), and then element 2 ("30"), that we will not find the value "25" since every element after element 2 will be greater than or equal to "30".
 +
 
 +
 
 +
Furthermore, in our phone book example, we would know that once we have reached a name that would come after "McAdams" alphabetically, we can stop our search because "McAdams" must not be in the phone book.
  
Furthermore, in our phone book example, we would know that once we have reached a name that would come after "McAdams" alphabetically, we can stop our search because "McAdams" must not be in the phone book.<br><br>
 
  
 
A simple addition to our for loop will do the trick:
 
A simple addition to our for loop will do the trick:
<pre>
+
 
 +
{{CodeBlock
 +
|Code=
 +
 
 
searchValue >=list[counter]
 
searchValue >=list[counter]
</pre>
 
  
This completes our linear search algorithm as follows:
+
}}
<pre>
+
 
 +
This completes our [[Glossary#linear search|linear search]] algorithm as follows:
 +
 
 +
{{CodeBlock
 +
|Code=
 +
 
 
public static int linearSearch (int[] list, int searchValue)
 
public static int linearSearch (int[] list, int searchValue)
 
{
 
{
Line 66: Line 99:
 
return result;
 
return result;
 
}//linearSearch()
 
}//linearSearch()
</pre>
 
  
Let us sum up what we have covered.  A linear search checks every element in an array in sequential order for a search value.  The efficient linear search algorithm stops searching when: 1) we stop searching once our search value has been located, 2) our array is sorted in ascending order and we stop searching after a value is greater than our search value, or 3) we have reached the end of the array.  A linear search is not the best search to implement, but it is simple and does the trick.
+
}}
  
==Selection Searching==
+
Let us sum up what we have covered.  A [[Glossary#linear search|linear search]] checks every element in an array in [[Glossary#sequential|sequential]] order for a search value.  The efficient linear search algorithm stops searching when: 1) our search value has been located, 2) we have reached a value which is greater than our search value, or 3) we have reached the end of the array.  A linear search, sometimes referred to as a [[Glossary#sequential|sequential]] search, is not the best search to implement, but it is simple and does the trick.
  
Selection searches are often used in instances where the ''k''th smallest item must be found. The easiest way to do this is to first sort the array into ascending (or descending) order, and then iterate through each item until the conditions have been satisfied.
 
  
The idea behind a selection sort is very simple: iterate through each element in the array, and for each element look at all remaining elements to see if there is something smaller that should be in this position. If there is, exchange the two values.
+
Complete the [[More With Arrays Review Questions and Exercises#searching arrays q|review questions]] to apply your knowledge of linear searching.
  
Example: sort this array
 
<pre>
 
|30|10|20|40|60|
 
</pre>
 
  
1) Outer loop: iterate through each element
+
==Binary Search==
<pre>
+
A [[Glossary#binary search|binary search]] is a step up from the linear search.  We will revisit the telephone book example to see how the binary search works.
i = 0 (30)
+
</pre>
+
  
2) Inner loop: iterate through the remaining elements to find a smaller element that should be in this position
 
<pre>
 
j = 1 (10)
 
</pre>
 
  
3) Since the element at i is greater than the element at j, swap them - the array will now be:
+
'''Example''': Find "McAdams" in the telephone book.
<pre>
+
Let us recall how we searched for "McAdams" using the linear ([[Glossary#sequential|sequential]]) search.  We opened the phone book to the first page, then flipped to the second page, continuing page by page until reaching the M’s, and finally find McAdams, if it was in the phone book.
|10|30|20|40|60|
+
</pre>
+
  
4) Again with the inner loop, we will move to the next element and compare:
+
Is that realistic?  No!  What we ''would'' do is open to the middle of the phone book. Then we would check if M's are on the right, or the left of this page.  If M was on the right, we would discard all the pages on the left and again cut this section in half, determine if M is on the right or left, and continue cutting and discarding the phone book until the correct page has been located.
<pre>
+
i = 0 (10), j = 2 (20)
+
</pre>
+
  
Since all the other elements in the list are greater than the 0th (10), nothing else will happen for this outer loop.
+
This is the idea of the binary search.  If we are searching for an element in a sorted array, we can inspect a single item and eliminate half of the array each inspection.<br><br>
  
Loop 2: In the outer loop, we will move to the next element (1) and loop through the remaining elements (starting at 2)
+
Now let us revisit our sorted array to see how a binary search would work.  We are looking for “40” in this array:
<pre>
+
i = 1 (30), j = 2(20)
+
</pre>
+
  
Since the element at i is greater than the element at j, swap them and continue, giving us this array (which is now sorted!)
+
{{OutputBlock
<pre>
+
|Code=
|10|20|30|40|60|
+
</pre>
+
  
Here is an example of a very simple selection sorting algorithm:
+
{{!}}10{{!}}20{{!}}30{{!}}40{{!}}60{{!}} 
  
<pre>
+
}}
// Selection sort algorithm
+
  
public static void selectionSort(int[] haystack) {
+
1) Inspect the middle element (30).
    for (int i = 0; i < haystack.length - 1; i++) {
+
        for (int j = i + 1; j < haystack.length; j++) {
+
            if (haystack[i] > haystack[j]) {
+
                //... Exchange elements
+
                int temp = haystack[i];
+
                haystack[i] = haystack[j];
+
                haystack[j] = temp;
+
            }
+
        }
+
    }
+
}
+
</pre>
+
  
After the list has been sorted, you can then iterate through the list simply using a ''for'' loop.
+
2) Is "40" this middle element, or to the left, or right of the middle element?  It's on the right.
  
<pre>
+
3) Eliminate the left portion of the array. We are left with the array below.
// selectionSearch - returns the index at which the value was found, or -1 if it was not found
+
  
public static int selectionSearch(int needle, int[] haystack) {
+
{{OutputBlock
    for (int i = 0; i < haystack.length; i++) {
+
|Code=
        if (needle == haystack[i]) {
+
            return i;  // if the value was found, return its index
+
        }
+
    }
+
    return -1;  // if the value has not been found return -1
+
}
+
</pre>
+
  
==Binary Search==
+
{{!}}30{{!}}40{{!}}50{{!}}
A binary search is a step up from the linear search.  To help understand how the binary search works, let us revisit our telephone book example. <br><br>
+
  
'''Example''': find "McAdams" in the telephone book.<br>
+
}}
Let us recall how we searched for "McAdams" using the linear search.  We opened the phone book to the first page, then flipped to the second page, continuing page by page until reaching the M’s, and finally find McAdams, if it was in the phone book.  <br><br>
+
  
Is that realistic?  No!  What we would do is open to the middle of the phone book. Then we would check if M's are on the right, or the left of this page.  If M was on the right, we would discard all the pages on the left and again cut this section in half, determine if M is on the right or left, and continue cutting the phone book and discarding until the correct page has been located. <br><br>
+
4) Inspect the new middle element (40).
  
This is the idea of the binary search. If we are searching for an element in a sorted array, we can inspect a single item and eliminate half of the array each inspection.<br><br>
+
5) Is "40" this middle element, or to the left, or right of the middle element? It's the middle element.  
 
+
Now let us revisit our sorted array to see how a binary search would work.  We are looking for “40” in this array: <br><br>
+
  
            |10|20|30|40|60|  
+
6) Binary search is done. We have found the "40" in index 3.
  
1) Inspect the middle element (30).  <br>
+
Now that you understand how the binary search works, let's look at the [[Glossary#binary search|binary search]] algorithm:
2) Is "40" this middle element, or to the left, or right of the middle element?  It's on the right.  <br>
+
<div id="binary search algorithm"></div>
3) Eliminate the left portion of the array.<br><br>
+
  
            |30|40|50|
 
  
4) Inspect the new middle element (40).<br>
+
{{CodeBlock
5) Is "40" this middle element, or to the left, or right of the middle element?  It's the middle element.  <br>
+
|Code=
6) Binary search is done - we have found the "40" in element 3.<br><br>
+
  
Now that you understand how the binary search works, let's look at the Binary Search Algorithm:
 
<pre>
 
 
public static int binarySearch(int[] list, int searchValue)
 
public static int binarySearch(int[] list, int searchValue)
 
{
 
{
Line 185: Line 166:
 
right = list.length-1;  //right index starts at the last element
 
right = list.length-1;  //right index starts at the last element
  
while ((left <= right) && (result == -1))
+
while ((left <= right) && (result == -1))   //left and right boundaries do not overlap and searchValue is not found
{//left and right boundaries do not overlap and searchValue is not found
+
{
 
+
 
middle = (left + right) / 2;
 
middle = (left + right) / 2;
middleElement = list(middle);
+
middleElement = list[middle];
  
if (middleElement == searchValue)
+
if (middleElement == searchValue)   //we have found our searchValue
{//we have found our searchValue
+
{
 
result = middle;
 
result = middle;
 
}
 
}
 
+
else if (middleElement < searchValue)   //need to discard left portion of array
else if (middleElement < searchValue)
+
{
{//need to discard left portion of array
+
 
left = middle + 1;
 
left = middle + 1;
 
}
 
}
 
+
else if (middleElement > searchValue)   //need to discard right portion of array
else if (middleElement > searchValue)
+
{
{need to discard right portion of array
+
 
right = middle – 1;
 
right = middle – 1;
 
}
 
}
Line 208: Line 186:
 
return result;
 
return result;
 
}//binarySearch()
 
}//binarySearch()
</pre>
 
  
Let us recap what we have learned about the binary search.  A binary search is much more efficient than a linear search.  If we compare the middle value of an array with our search value, this comparision will eliminate half the array, reducing the amount of numbers needing to be compared.
+
}}
 +
 
 +
Let us recap what we have learned about the [[Glossary#binary search|binary search]].  A binary search is more efficient than a linear search.  By comparing the array's middle value with the search value, we eliminate half the array and reduce the amount of numbers to be compared.<br><br>
 +
 
 +
Complete the [[More With Arrays Review Questions and Exercises#searching arrays q|review questions]] to apply your knowledge of binary searching.  Also, complete the [[More With Arrays Review Questions and Exercises#searching arrays e|Apply the Binary Search]] exercise for more practice.
 +
 
 +
 
 +
==Section Summary==
 +
To recap this section. In this section we learned two search algorithms, Linear search and Binary search. The two search algorithm are providing a good method to search for and element in the array. Out of the two algorithms Binary search is more efficient then linear search by having smaller time complexity. In this section we brought an example with Integers array but this search methods can be adapted to search any type of object. Please note that this topic is covered briefly, the further explanation will be provided in the COMP 1020 courses where algorithms and arrays will be discussed further
 +
 
 +
}}

Latest revision as of 03:27, 8 December 2011

COMP 1010 Home > More With Arrays > Searching Arrays


Introduction

We learned how to create arrays and you should know that an Array is a type of list that can contain one type of object. There will be situations where you will be a need to search for a particular value in an array. Today there are many algorithms to solve this problem. These algorithms have different inefficiencies which are measured as a "time complexity". In this Chapter we are going to discuss two search algorithms; Linear Search and Binary Search. Linear search is a brute force approach and Binary Search utilizes the middle index as a lower or upper bound for its search.

Linear Search

A linear search can be used to locate a value in an array. A linear search checks each element one after another (from left to right or right to left) for a match to our search value until one of two things happens:

  • our search value has been found
  • we have reached the end of the array (in other words, we have not found the value.)


Example: Find "McAdams" in the telephone book.

Using a linear search, the algorithm would open the phone book to page 1. On page 1, we would check every name checking if it matches "McAdams". If "McAdams" is not on the first page, we would flip to the second page, and again, check every name for a match to "McAdams". We would continue this until eventually we have found the "McAdams" entry in the phone book, or there was no match.


Here is the algorithm for completing a linear search:

 public static int linearSearch (int[] list, int searchValue)
{
	int counter;   //loop iterator
	int result;    //store element where searchValue is found

	result = -1;   //return -1 if searchValue is not found

	for (counter=0; result == -1 && counter<list.length; counter++)   //loop until searchValue is found or the array is out of bounds.
	{
		if (list[counter] == searchValue)   //found searchValue!  end loop.
		{
			result = counter;
		}
	}//for
	return result;
}//linearSearch() 

Our linear search algorithm can be one step more efficient if our array is sorted in ascending order. Here is an example of an unsorted array, and that same array after being sorted. (We do not need to worry about sorting at this point, just imagine the array is sorted for you.)


 Unsorted array:                              

|10|30|60|40|20|     

Sorted array:

|10|20|30|40|60| 

Using the sorted array above, if we were searching for the value "25", we would know after checking element 0 ("10"), element 1 ("20"), and then element 2 ("30"), that we will not find the value "25" since every element after element 2 will be greater than or equal to "30".


Furthermore, in our phone book example, we would know that once we have reached a name that would come after "McAdams" alphabetically, we can stop our search because "McAdams" must not be in the phone book.


A simple addition to our for loop will do the trick:

 searchValue >=list[counter] 

This completes our linear search algorithm as follows:

 public static int linearSearch (int[] list, int searchValue)
{
	int counter;
	int result;

	result = -1;
	for (counter=0; result == -1 && counter<list.length && searchValue>=list[counter]; counter++)
	{
		if (list[counter] == searchValue)
		{
			result = counter;
		}
	}//for
	return result;
}//linearSearch() 

Let us sum up what we have covered. A linear search checks every element in an array in sequential order for a search value. The efficient linear search algorithm stops searching when: 1) our search value has been located, 2) we have reached a value which is greater than our search value, or 3) we have reached the end of the array. A linear search, sometimes referred to as a sequential search, is not the best search to implement, but it is simple and does the trick.


Complete the review questions to apply your knowledge of linear searching.


Binary Search

A binary search is a step up from the linear search. We will revisit the telephone book example to see how the binary search works.


Example: Find "McAdams" in the telephone book. Let us recall how we searched for "McAdams" using the linear (sequential) search. We opened the phone book to the first page, then flipped to the second page, continuing page by page until reaching the M’s, and finally find McAdams, if it was in the phone book.

Is that realistic? No! What we would do is open to the middle of the phone book. Then we would check if M's are on the right, or the left of this page. If M was on the right, we would discard all the pages on the left and again cut this section in half, determine if M is on the right or left, and continue cutting and discarding the phone book until the correct page has been located.

This is the idea of the binary search. If we are searching for an element in a sorted array, we can inspect a single item and eliminate half of the array each inspection.

Now let us revisit our sorted array to see how a binary search would work. We are looking for “40” in this array:

 |10|20|30|40|60| 

1) Inspect the middle element (30).

2) Is "40" this middle element, or to the left, or right of the middle element? It's on the right.

3) Eliminate the left portion of the array. We are left with the array below.

 |30|40|50| 

4) Inspect the new middle element (40).

5) Is "40" this middle element, or to the left, or right of the middle element? It's the middle element.

6) Binary search is done. We have found the "40" in index 3.

Now that you understand how the binary search works, let's look at the binary search algorithm:


 public static int binarySearch(int[] list, int searchValue)
{
	int left;               //left element index
	int right;              //right element index
	int middle;             //middle element index
	int result;             //element that searchValue was found in
	int middleElement;      //middle value (comparing)

	result = -1;            //return -1 if searchValue is not found
	left = 0;               //left index starts at the first element
	right = list.length-1;  //right index starts at the last element

	while ((left <= right) && (result == -1))   //left and right boundaries do not overlap and searchValue is not found
	{
		middle = (left + right) / 2;
		middleElement = list[middle];

		if (middleElement == searchValue)   //we have found our searchValue
		{
			result = middle;
		}
		else if (middleElement < searchValue)   //need to discard left portion of array
		{
			left = middle + 1;
		}
		else if (middleElement > searchValue)   //need to discard right portion of array
		{
			right = middle – 1;
		}
	}//while
	return result;
}//binarySearch() 

Let us recap what we have learned about the binary search. A binary search is more efficient than a linear search. By comparing the array's middle value with the search value, we eliminate half the array and reduce the amount of numbers to be compared.

Complete the review questions to apply your knowledge of binary searching. Also, complete the Apply the Binary Search exercise for more practice.


Section Summary

To recap this section. In this section we learned two search algorithms, Linear search and Binary search. The two search algorithm are providing a good method to search for and element in the array. Out of the two algorithms Binary search is more efficient then linear search by having smaller time complexity. In this section we brought an example with Integers array but this search methods can be adapted to search any type of object. Please note that this topic is covered briefly, the further explanation will be provided in the COMP 1020 courses where algorithms and arrays will be discussed further

Previous Page: Arrays of Strings Next Page: Sorting Arrays