[经典算法] 二分查找
题目说明:
二分查找法是对一组有序的数字中进行查找,传递相应的数据,进行比较查找到与原数据相同的数据,查找到了返回对应的数组下标,失败返回-1。
题目解析:
二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。
二分查找可以解决(预排序数组的查找)问题:只要数组中包含T(即要查找的值),那么通过不断缩小包含T的范围,最终就可以找到它。其算法流程如下:
1、一开始,范围覆盖整个数组。
2、将数组的中间项与T进行比较,如果T比数组的中间项要小,则到数组的前半部分继续查找,反之,则到数组的后半部分继续查找。
3、如此,每次查找可以排除一半元素,范围缩小一半。就这样反复比较,反复缩小范围,最终就会在数组中找到T,或者确定原以为T所在的范围实际为空。
程序代码:
#include <gtest/gtest.h> using namespace std; // 递归函数 template<typename T> int BinarySearch(T* data, int low, int high, int key) { if (low > high) { return -1; } int mid = (high + low) / 2; if (data[mid] == key) { return mid; } else if (data[mid] > key) { return BinarySearch(data, low, mid - 1, key); } else { return BinarySearch(data, mid + 1, high, key); } } // 非递归函数实现 template<typename T> int BinarySearch2(T* data, int len, int key) { int low = 0; int high = len - 1; while (low <= high) { int mid = (low + high) /2; if (data[mid] == key) { return mid; } else if(data[mid] > key) { high = mid -1; } else { low = mid + 1; } } return -1; } TEST(POJS, tBinarySearch) { int d1[] = {1,2,3,4,5,6,7,8}; ASSERT_EQ(BinarySearch(d1, 0, 7, 4),3); ASSERT_EQ(BinarySearch2(d1, 8, 4),3); ASSERT_EQ(BinarySearch(d1, 0, 7, 9),-1); ASSERT_EQ(BinarySearch2(d1, 8, 9),-1); int d2[] = {2}; ASSERT_EQ(BinarySearch(d2, 0, 0, 2),0); ASSERT_EQ(BinarySearch2(d2, 1, 2),0); ASSERT_EQ(BinarySearch(d2, 0, 0, 3),-1); ASSERT_EQ(BinarySearch2(d2, 1, 3),-1); }