二分查詢是一種在有序陣列中查詢某一特定元素的搜尋演算法。搜尋過程從陣列的中間元素開始,如果中間元素正好是要查詢的元素,則搜尋過程結束;如果某一特定元素大於或者小於中間元素,則在陣列大於或小於中間元素的那一半中查詢,而且跟開始一樣從中間元素開始比較。如果在某一步驟陣列為空,則代表找不到。這種搜尋演算法每一次比較都使搜尋範圍縮小一半。
時間複雜度為o(log n)
例如對於構成的有序序列對應的查詢樹:
最簡單的二分查詢演算法:
即找到返回下標,找不到返回-1,(座標範圍:[0~nums.size() - 1])
#include #include #include #include #include #include #include #include using namespace std;
int binarysearch(vector& nums, int target)
else if(nums[mid] < target)
else
}return -1;
}int main()
; cout << binarysearch(vec, 3);
return 0;
}
查詢第乙個與target相等的元素位置,找不到返回-1
int binarysearchleft(vector& nums, int target)
else
}if (left <= (int)nums.size() - 1 && nums[left] == target)
return -1;
}
查詢最後乙個與target相等的元素位置,找不到返回-1
int binarysearchright(vector& nums, int target)
else
}if (right >= 0 && nums[right] == target)
return -1;
}
查詢最後乙個小於key的元素
#include #include #include #include #include #include #include #include using namespace std;
int binarysearch(vector& nums, int target)
else if(nums[mid] < target)
}return right;
}int main()
; cout << binarysearch(vec, 7);
return 0;
}
查詢第乙個大於key的元素
#include #include #include #include #include #include #include #include using namespace std;
int binarysearch(vector& nums, int target)
else if(target < nums[mid])
}return left;
}int main()
; cout << binarysearch(vec, 5);
return 0;
}
如果返回nums.size()則說明不存在。
查詢第乙個等於或者小於key的元素
#include #include #include #include #include #include #include #include using namespace std;
int binarysearch(vector& nums, int target)
else
}if (nums[left] != target)
return left;
}int main()
; cout << binarysearch(vec, 5);
return 0;
}
查詢最後乙個等於或者大於key的元素
#include #include #include #include #include #include #include #include using namespace std;
int binarysearch(vector& nums, int target)
else
}if (nums[right] != target)
return right;
}int main()
; cout << binarysearch(vec, 5);
return 0;
}
stl中與二分查詢相關的函式有4個,分別是lower_bound, upper_bound, equal_range和binary_search,下面通過乙個簡單的例子說明各個函式的使用方法。
#include #include #include using namespace std;
int main()
; //已排序
vectorv(a, a + 6);
typedef vector::iterator it; //迭代器型別
it st = v.begin(), ed = v.end(); //起始迭代器
it p1 = lower_bound(st, ed, 2);//>=2的第乙個位置
printf("%d\n", p1 - st); // 1
it p2 = upper_bound(st, ed, 2);//>2的第乙個位置
printf("%d\n", p2 - st); // 4
pairp = equal_range(st, ed, 2); //==2的位置
printf("%d-%d\n", p.first - st, p.second - st); // 1-4
bool exist = binary_search(st, ed, 2); //2是否存在
printf("%d\n", exist); //1 (是)
}
其中每個函式實現的功能如下:
binary_search:查詢某個元素是否出現。
lower_bound:查詢第乙個大於或等於某個元素的位置。
upper_bound:查詢第乙個大於某個元素的位置。
equal_range:查詢某個元素出現的起止位置。注意,終止位置為最後一次出現的位置加一。
其中lower_bound和upper_bound的功能可能比較彆扭,可以這樣看:對於已排序的陣列1 2 2 2 3 4,元素2出現了3次,第一次出現的位置為1,最後一次的位置為3,lower_bound即為這個第一次出現的位置,而upper_bound本意是要標誌最後一次出現的位置,但stl中習慣使用左閉右開的區間,於是upper_bound返回的結果應該為最後一次出現的位置的下乙個位置。當查詢的元素一次都未出現時,二者返回的結果都是第乙個大於該元素的位置。
參考:
你真的會二分查詢嗎?
看到這個標題無論你是處於怎樣的心理進來看了,我覺得都是值得的。因為這個問題太簡單,任何乙個開始接觸 真正 演算法基本都是從二分查詢開始的。至於二分查詢都不知道是什麼的可以先去找別的資料看下,再來看這篇文章。既然很簡單,那麼我們開始一起寫乙個吧,要求是對num 不減序列在區間 0,7 進行查詢,當然我...
你真的會二分查詢嗎?
引用請註明出處 看到這個標題無論你是處於怎樣的心理進來看了,我覺得都是值得的。因為這個問題太簡單,任何乙個開始接觸 真正 演算法基本都是從二分查詢開始的。至於二分查詢都不知道是什麼的可以先去找別的資料看下,再來看這篇文章。既然很簡單,那麼我們開始一起寫乙個吧,要求是對num 不減序列在區間 0,7 ...
你真的會二分查詢嗎?
看到這個標題無論你是處於怎樣的心理進來看了,我覺得都是值得的。因為這個問題太簡單,任何乙個開始接觸 真正 演算法基本都是從二分查詢開始的。至於二分查詢都不知道是什麼的可以先去找別的資料看下,再來看這篇文章。既然很簡單,那麼我們開始一起寫乙個吧,要求是對num 不減序列在區間 0,7 進行查詢,當然我...