您的位置:首页 > 理论基础 > 数据结构算法

重学数据结构系列之——静态查找表查找算法

2016-04-18 17:53 218 查看

1.认识查找

就是在一个集合里面找到某个元素。集合就叫查找表
通常对查找表有 4 种操作:

查找:在查找表中查看某个特定的记录是否存在

检索:查找某个特定记录的各种属性

插入:将某个不存在的数据元素插入到查找表中

删除:从查找表中删除某个特定元素

如果对查找表只执行前两种操作,则称这类查找表为 静态查找表(static search table)。静态查找表建立以后,就不能再执行插入或删除操作,查找表也不再发生变化。对应的,如果对查找表还要执行后两种操作,则称这类查找表为
动态查找表(dynamic search table)

下面的查找算法都是针对静态查找表的,比如顺序查找、折半查找、分块查找等;而对于动态查找表,往往使用二叉平衡树、B-树或哈希表来处理。

2.查找算法的好坏

用平均查找长度来比较(我们当做查找表中的每个元素被查找的概率都是相等的),平均查找长度的计算:将查找每个元素时的比较次数加起来,再除以元素总个数n

3.顺序查找算法

就是跟查找表的每个元素逐一比较,找到就返回索引,找不到返回-1

简单的查找代码:(分为有序表的查找和无序表的查找)下面是有序表的查找,无序的查找把下面的search函数的else if 语句删除即可

时间复杂度O(n)
#include <iostream>
#include <cstring>

using namespace std;

class Vector {
private:
int size, length;
int *data;
public:
Vector(int input_size) {
size = input_size;
length = 0;
data = new int[size];
}
~Vector() {
delete[] data;
}
bool insert(int loc, int value) {
//插入位置的范围判断
if (loc < 0 || loc > length) {
return false;
}
if (length >= size) {
//若当前线性表的长度大于等于容量时,就扩容
expand();
}
//将loc后面的数据全部后移,从最后一个元素开始移
for (int i = length; i > loc; --i) {
data[i] = data[i - 1];
}
//插入该位置,并长度+1
data[loc] = value;
length++;
return true;
}
void expand() {
int * old_data = data;
size = size * 2;
data = new int[size];
for (int i = 0; i < length; ++i) {
data[i] = old_data[i];
}
delete[] old_data;
}
int search(int value) {
for (int i = 0; i < length; i++) {
if (data[i] == value) {
return i;
}else if (data[i] > value) {
return -1;
}
}
return -1;
}
bool remove(int index) {
if (index < 0 || index >= length) {
return false;
}
for (int i = index + 1; i < length; ++i) {
data[i - 1] = data[i];
}
length = length - 1;
return true;
}
void print() {
for (int i = 0; i < length; ++i) {
if (i > 0) {
cout << " ";
}
cout << data[i];
}
cout << endl;
}
};
int main() {
Vector a(100);
a.insert(0, 2);
a.insert(1, 4);
a.insert(2, 6);
a.insert(3, 8);
a.insert(4, 10);

cout << a.search(4) << endl;
cout << a.search(5) << endl;
return 0;
}


结果:



4.有序表查找的优化——折半查找

由于相当于向二叉树那样分叉,时间复杂度就是O(logn)

把上面的search函数改了即可
int search(int value) {
//初始化二分查找的左右范围
int left = 0, right = length -1;
//左边必须小于等于右边
while (left <= right) {
int mid = (left + right) / 2;
if (data[mid] == value) {
return mid;
}
//暂时找不到就相应更新左或右的范围
else if (data[mid] < value) {
left = mid + 1;
}else{
right = mid -1;
}
}
//来到这说明left > right,查找不成功
return -1;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: