java 12:數組的搜索——線性查找及二分法查找

Searching is the process of looking for a specific element in an array—for example, discover-
ing whether a certain score is included in a list of scores. Searching is a common task in com-
puter programming. Many algorithms and data structures are devoted to searching. This

section discusses two commonly used approaches, linear search and binary search.

所以我們今天說的就是兩種常見的對數組搜索特定的元素的方法——線性搜索及二分法搜索

1 無序數組——線性搜索

The linear search approach compares the key element key sequentially with each element in
the array. It continues to do so until the key matches an element in the array or the array is
exhausted without a match being found. If a match is made, the linear search returns the index
of the element in the array that matches the key. If no match is found, the search returns -1.

線性搜索也就是對數組進行遍歷,在遍歷過程中比較要尋找的數值與當前的元素,如果兩者相等,則返回該index,否則遍歷完還沒找到就返回-1;

public class LinearSearch
{
	public static int linearSearch(int [] a,int key)
	{
		for(int i=0;i<a.length;i++)
		{
			if(key==a[i]) return i;
		}
		return -1;
		
	}	
}
線性搜索的數組可以是任意的數組,無論是否有序。他的平均搜索次數是數組長度的一半,所以,線性搜索雖然簡單粗暴,但是不適合用於大數組中,也就是長度很長的數組,因爲這樣平均搜索時間隨着長度增長而增加

2 有序數組——二分法搜索

Binary search is the other common search approach for a list of values. For binary search to
work, the elements in the array must already be ordered. Assume that the array is in ascend-
ing order. The binary search first compares the key with the element in the middle of the array.
Consider the following three cases:
■ If the key is less than the middle element, you need to continue to search for the key
only in the first half of the array.
■ If the key is equal to the middle element, the search ends with a match.
■ If the key is greater than the middle element, you need to continue to search for the
key only in the second half of the array.

二分法是在對付有序數組時候很有利的一個工具,二分查找法首先將key與數組中間的元素比較,這樣數組就分爲了左右兩半。

1)如果key 小於該元素,那麼我們只需要將key在左半部分中查找

2)如果key 大於該元素,那麼我們只需要將key在有半部分中查找

3)如果key等於該元素,我們直接返回

所以,在二分查找中,我們每一次比較就能淘汰掉一半的元素,加入我們有n個元素,那麼第一次比較後剩下n/2,第二次比較剩下n/2/2 ,第k次比較就剩n/2k個 ,那麼當k=Log2n時候,就只剩下一個元素,那麼也就是說最壞的情況下我們只需要做Log2n+1次比較就可以找到,對於一個有1024個元素的數組,最壞最壞情況也只需要比較11次。

The portion of the array being searched shrinks by half after each comparison. Let low and
high denote, respectively, the first index and last index of the array that is currently being
searched. Initially, low is 0 and high is list.length–1. Let mid denote the index of the
middle element. So mid is (low + high)/2. 

public class BinarySearch
{
	public static int binarySearch(int [] a,int key)
	{
		int low=0;
		int high=a.lenth-1;
		
		while(low<=high)
		{
			int mid=(low+high)/2;
			if(key==a[mid]) return mid;
			if(key<a[mid])
			{
				high=mid-1;	
			}else 
			{
				low=mid+1
			}
		}
		<span style="color:#ff0000;">return -low-1;</span>
		
	}
}
要注意這裏如果沒找到我們沒有返回-1 而是返回-low-1;這是因爲當我們沒有找到時候,low的位置是該元素要插入的位置,但是爲什麼不返回-low呢? 因爲如果我們key比所有的元素都小,那麼最後一次比較是停留在index=0的位置,這時候low=0,那麼我們返回給調用者的值就是0了,而不是一個負數,這樣我們拿到0並不知道他是沒匹配到,還是該元素就在第一個元素。所以我們要保證如果找不到就返回一個負數。所以就多減個1 這樣-1就表示沒找到並且該元素必須插到0的位置上。測試一下:

public static void main(String [] args)
	{
		int[] list = {2, 4, 7, 10, 11, 45, 50, 59, 60, 66, 69, 70, 79};
		int i = BinarySearch.binarySearch(list, 2); // Returns 0
		int j = BinarySearch.binarySearch(list, 11); // Returns 4
		int k = BinarySearch.binarySearch(list, 12); // Returns –6
		int l = BinarySearch.binarySearch(list, 1); // Returns –1
		int m = BinarySearch.binarySearch(list, 3); // Returns –2
		System.out.println("i="+i+",j="+j+",k="+k+",l="+l+",m="+m);
	}
總結:線性查找用於無序的小數組中查找是非常好的,但是對於大型的數組就非常的低效了;而對於已經排好序的數組,二分查找是非常高校的一種方法








發佈了112 篇原創文章 · 獲贊 15 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章