一、顺序查找
条件:无序或有序队列。
原理:按顺序将查找元素与每个元素比较,直到找到查找元素为止。
时间复杂度:O(n)
int SequenceSearch(int arr[], int value, int n)
{
int i;
for(i = 0; i < n; i++)
if(arr[i] == value)
return i;
return -1;
}
二、二分查找(折半查找)
条件:有序数组
原理:
查找过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;
如果查找元素大于(小于)中间元素,则在数组大于(小于)中间元素的那一半区间中查找,而且跟开始一样从中间元素开始比较。
如果在某一步骤数组为空,则代表找不到。
这种搜索算法每一次比较都使搜索范围缩小一半。
时间复杂度:O(logn)
int BinarySearch(int arr[], int value, int n)
{
int low = 0;
int high = n-1;
int mid;
while(low <= high)
{
mid = (low + high) / 2;
if(arr[mid] == value)
return mid;
else if(arr[mid] > value)
high = mid - 1;//区间新终点
else
low = mid + 1; //区间新起点
}
return -1;
}
//递归版
int BinarySearch(int arr[], int value, int low, int high)
{
int mid = low + (high - low) / 2;
if(arr[mid] == value)
return mid;
else if(arr[mid] > value)
return BinarySearch(a, value, low, mid - 1);
else
return BinarySearch(a, value, mid + 1, high);
}
三、二叉排序树查找
条件:先创建二叉排序树,其性质:
1. 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
2. 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
3. 它的左、右子树也分别为二叉排序树。
原理:
在二叉查找树B中查找key的过程为:
1. 若B是空树,则搜索失败,否则:
2. 若key等于B的根节点的数据域之值,则查找成功;否则:
3. 若key小于B的根节点的数据域之值,则递归查找左子树;否则:
4. (key大于B的根节点的数据域之值)递归查找右子树。
时间复杂度:O(log2(n))
//树结点
typedef struct tNode
{
int tdata;
tNode *lchild; //指向左孩子结点
tNode *rchild; //指向右孩子结点
}*PTRNODE
//插入算法即二叉查找树的构建/生成,插入key到合适位置
void tInsert(PTRNODE &tp, int key)
{
if (NULL == tp)
{
tp = new tNode;
tp->tdata = key;
tp->lchild = tp->rchild =NULL;
}
else if (key < tp->tdata)
{
tInsert(tp->lchild, key);
}
else
{
tInsert(tp->rchild, key);
}
}
//查找算法
void tSearch(PTRNODE &tp, int key)
{
if (NULL == tp)
{
cout<<"Error\n未找到与关键字 \""<<key<<"\" 相匹配的数据元素"<<endl;
return;
}
if (key < tp->tdata)
{
//打印访问路径
cout<<tp->tdata<<"->";
tSearch(tp->lchild, key);
}
else if(key > tp->tdata)
{
cout<<tp->tdata<<"->";
tSearch(tp->rchild, key);
}
else //查找成功
{
cout<<tp->tdata<<endl;
}
}
四、平衡二叉树查找(红黑树)
五、B/B+树查找
六、哈希表法(散列表)
条件:先创建哈希表(散列表),可能是数组实现
原理:根据键值方式(Key value)进行查找,通过散列函数,定位数据元素。
时间复杂度:几乎是O(1),取决于产生哈希冲突的多少。
常见散列函数:
1)除余法:H(key) = key%p,p是不大于表长的质数(素数)
2)直接定址发:H(key) = a*key+b
哈希冲突解决:不同key的H(key)相同
1)开放地址法:探测可用位置
2)链接地址法:相同哈希值的多个关键字存放在同个地址的链表里
3)桶地址:相同哈希值的多个关键字存放在同个地址的桶里