顺序查找
假设待查找元素在 i 位, 则找到需要进行 n-i+1 次比较
平均查找长度为:
折半(二分)查找
#include<iostream>
#include<vector>
using namespace std;
int Binary_Search(vector<int>& list, int key) {
int low = 0, high = list.size() - 1, mid;
while (low <= high) {
mid = (low + high) / 2; // 取中间位置
if (list[mid] == key) {
return mid;
}
else if (list[mid] > key) {
high = mid - 1; // 从前半部分继续查找
}
else {
low = mid + 1; // 从后半部分继续查找
}
}
// 查找失败, 返回 -1
return -1;
}
int main() {
vector<int>list = { 1,2,4,6,10,100,230,300 };
cout << Binary_Search(list, 10);
return 0;
}
折半查找可以等价于一颗二叉树
一个节点的查找次数 等于其所在的高度, 而每一层有 个节点(h0=1)
因此平均查找长度为:
其比较次数不会超过树的高度
因此折半查找的时间复杂度为
分块查找
块内可以无序, 块间有序, 索引使用折半查找, 块内使用顺序查找
#include<iostream>
#include<vector>
using namespace std;
class BlockSearch {
private:
vector<int> index; // 索引表
vector<int>* list; // 块
public:
// 构造函数
BlockSearch(vector<int>& index) :index(index) {
list = new vector<int>[index.size()];
}
// 析构函数
~BlockSearch() { delete[] list; };
// 插入元素
void insert(int value) {
// 通过索引找到对应的块
int i = binarySearch(value);
if (i != -1) {
list[i].push_back(value);
}
else {
cout << "插入失败\n";
}
}
// 找到返回 true
bool search(int data) {
int i = binarySearch(data);
if (i != -1) {
// 在块内顺序查找
for (int j = 0; j < list[i].size(); j++) {
if (data == list[i][j]) {
return true;
}
}
}
return false;
}
// 二分查找定位索引位置
int binarySearch(int data) {
int low = 0, high = index.size() - 1, mid;
while (low <= high) {
mid = (low + high) / 2;
if (index[mid] > data) {
high = mid - 1;
}
else {
low = mid + 1;
}
}
return low;
}
};
int main() {
vector<int> index = { 10,20,30,40,50 };
BlockSearch bs(index);
bs.insert(11);
bs.insert(13);
bs.insert(39);
bs.insert(12);
bs.insert(22);
bs.insert(21);
bs.insert(19);
bs.insert(35);
bs.insert(33);
cout << bs.search(35);
return 0;
}