二分查找在面試中經常被問到,尤其是他的各種變化版本。二分查找就是把查找的鍵值和子數組中的中間鍵作比較,如果被找的鍵值小於中間鍵,則在左半部分繼續查找;如果大於中間值就在右半部分查找;否則就是要查找的元素。
基本二分查找
給定一個有序數組和一個關鍵字,找到該值在數組中的下標,否則返回-1
1 int BinarySearch(int a[],int size,int key) 2 { 3 int left = 0, right = size - 1; 4 while (left <= right) 5 { 6 int mid = left + (right - left) / 2; 7 if (a[mid] == key) return mid; 8 else if (a[mid] < key) left = mid + 1; 9 else right = mid - 1; 10 } 11 return -1; 12 }
二分查找變種
一、查找第一個與key相等的元素,也就是說等於查找key值的元素有很多,返回這些元素最左邊的元素的下標。
1 //查找第一個與key相等的元素 2 int BinarySearch(int a[],int size,int key) 3 { 4 int left = 0, right = size - 1; 5 while (left <= right) 6 { 7 int mid = left + (right - left) / 2; 8 if (a[mid] >= key) right = mid - 1; 9 else left = mid + 1; 10 } 11 if (left < size&&a[left] == key) 12 { 13 return left; 14 } 15 return -1; 16 }
二、查找最后一個與key相等的元素,也就是等於查找key值的元素有好多個,返回這些元素最右邊元素的下標。
1 //查找最后一個與key相等的元素 2 int BinarySearch(int a[],int size,int key) 3 { 4 int left = 0, right = size - 1; 5 while (left <= right) 6 { 7 int mid = left + (right - left) / 2; 8 if (a[mid] <= key) left = mid + 1; 9 else right = mid - 1; 10 } 11 if (right >=0 && a[right] == key) 12 { 13 return right; 14 } 15 return -1; 16 }
三、查找第一個等於或者大於key的元素,查找第一個等於或者大於key的元素,也就是說查找key值的元素有好多個,返回這些元素最左邊元素的下標;如果沒有等於key值的元素,則返回大於key的最左邊元素的下標。
1 //查找第一個等於或者大於key的元素 2 int BinarySearch(int a[],int size,int key) 3 { 4 //如果a[right]<key,則找不到等於或者大於key的值,直接返回-1 5 int left = 0, right = size - 1; 6 if (a[right] < key) return -1; 7 while (left <= right) 8 { 9 int mid = left + (right - left) / 2; 10 if (a[mid] >= key) right = mid - 1; 11 else left = mid + 1; 12 } 13 return left; 14 }
四、查找第一個大於key的元素。查找第一個大於key的值,也就是說返回大於key的最左邊元素的下標。
1 //查找第一個大於key的元素 2 int BinarySearch(int a[],int size,int key) 3 { 4 //如果a[right]<=key,則找不到大於key的值,直接返回-1 5 int left = 0, right = size - 1; 6 if (a[right] <= key) return -1; 7 while (left <= right) 8 { 9 int mid = left + (right - left) / 2; 10 if (a[mid] > key) right = mid - 1; 11 else left = mid + 1; 12 } 13 return left; 14 }
五、查找最后一個等於或者小於key的元素。查找最后一個等於或者小於key的元素,也就是說等於查找key值有很多,返回這些元素最右邊的元素的下標;如果沒有等於key值的元素,則返回小於key值的最右邊元素的下標。
1 //查找最后一個等於或者小於key的元素 2 int BinarySearch(int a[],int size,int key) 3 { 4 //如果a[left]>key,則找不到等於或者小於key的值,直接返回-1 5 int left = 0, right = size - 1; 6 if (a[left]>key) return -1; 7 while (left <= right) 8 { 9 int mid = left + (right - left) / 2; 10 if (a[mid] > key) right = mid - 1; 11 else left = mid + 1; 12 } 13 return right; 14 }
六、查找最后一個小於key的元素。查找最后一個小於key的元素,也就是說返回小於key的最右邊的元素下標。
1 //查找最后一個小於key的元素 2 int BinarySearch(int a[],int size,int key) 3 { 4 //如果a[left]>=key,則找不到=小於key的值,直接返回-1 5 int left = 0, right = size - 1; 6 if (a[left]>=key) return -1; 7 while (left <= right) 8 { 9 int mid = left + (right - left) / 2; 10 if (a[mid] >= key) right = mid - 1; 11 else left = mid + 1; 12 } 13 return right; 14 }
二分查找總結:
二分查找的步驟:
1、首先判斷出返回的是left還是right。因為我們知道最后跳出while(left<=right)循環條件是right<left並且right=left-1.最后right和left一定是卡在“邊界值”的左右兩邊,如果是比較值為key,查找大於等於key的元素,則邊界值就是等於key的所有元素的最左邊那個,其實應該返回left。
2、判斷比較符號