折半查找(二分查找)

 表中元素是按升序排列,將表中間位置記錄的關鍵字與查找關鍵字比較,如果兩者相等,則查找成功;否則利用中間位置記錄將表分成前、後兩個子表,如果中間位置記錄的關鍵字大於查找關鍵字,則進一步查找前一子表,否則進一步查找後一子表。重複以上過程,直到找到滿足條件的記錄,使查找成功,或直到子表不存在爲止,此時查找不成功。

 

#include <iostream>
#include <vector>
#include <time.h>
#include <algorithm>
using namespace std;
#define CNT 11

template<typename T>
std::ostream& operator<<(std::ostream& cout, const std::vector<T>& v)
{
	std::vector<T>::const_iterator ite = v.begin();
	for (; ite != v.end(); ++ite)
	{
		cout << *ite << " ";
	}
	cout << std::endl;
	return cout;
}
// 二分查找,返回下標,不存在返回-1
int BinarySearch(std::vector<int>& v,double val)
{
	if (v.empty()) return -1;
	if (!std::is_sorted(v.begin(), v.end())) 
		std::sort(v.begin(), v.end());
	int findCnt = 1;
	int left = 0,right = v.size() - 1,mid;
	while (left <= right)
	{
		mid = left + (right - left) / 2;
		std::cout << "第" << findCnt++ << "次查找,找到" << v[mid];
		if (v[mid] == val)
		{
			std::cout << "是目標值,停止查找!" << std::endl;
			return mid;
		}
		else if (v[mid] > val)
		{
			std::cout << ",比目標值大,繼續向左查找!" << std::endl;
			right = mid - 1;
		}
		else
		{
			std::cout << ",比目標值小,繼續向右查找!" << std::endl;
			left = mid + 1;
		}
	}
	return -1;
}
int main()
{
	srand(unsigned(time(NULL)));
	std::vector<int> v;
	std::cout << "排序前的序列爲:";
	for (int i = 0; i < CNT; ++i)
	{
		v.push_back(rand() % 100);
	}
	std::cout << v;

	int findNum = v.front();
	std::sort(v.begin(),v.end());
	std::cout << "排序後的序列爲:";
	std::cout << v;

	std::vector<double> findNumVec;
	findNumVec.push_back(findNum);
	findNumVec.push_back(1.1111);
	for (int i = 0; i < 2; ++i)
	{
		std::cout << "查找目標值:" << findNumVec[i] << std::endl;
		int idx = 0;
		if ((idx = BinarySearch(v, findNumVec[i])) != -1)
		{
			std::cout << "在下標爲 " << idx << " 處找到 " << findNumVec[i] << std::endl;
		}
		else
			std::cout << "不存在 " << findNumVec[i] << std::endl;
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章