常用查找算法
程序员文章站
2022-07-12 14:50:24
...
一、顺序搜索
顺序查找是在一个已知无(或有)序队列中找出与给定关键字相同的数的具体位置。顺序查找适合小规模的数据
原理
从序列的第一个元素开始,依次与关键字进行比较,直到找到目标关键字或者查找失败。
1、从表中的第一个元素开始,依次与关键字比较。
2、若某个元素与关键字匹配,则查找成功。
3、若直至最后一个元素还未匹配关键字,则查找失败。
时间复杂度
顺序查找平均关键字匹配次数为表长的一半,其时间复杂度为O(n)。
插入数据时可在O(1)时间内完成。但是对于数据规模较大时,效率较低。
实现
int search(int a[],int n,int target)
{
int i;
for(i=0;i<n;i++){
if(target==a[i])
return i;
}
return -1;
}
二、分块搜索
分块查找又称索引顺序查找,是顺序查找和折半查找的一种改进方法;分块查找由于只要求索引表是有序的,对块内节点没有排序要求,因此特别适合于节点动态变化的情况。
原理
将n个数据元素“按块有序”划分为m块(m<n)。每一块中的结点不必有序,但块与块之间必须“按块有序”。即第1块中任一元素的关键字都必须小于第2块中任一元素的关键字;而第2块中任一元素都必须小于第3块中的任一元素,...。
查找步骤
1、先选取各块中的最大关键字构成一个索引表;2、先对索引表进行二分查找或顺序查找,以确定待查记录在哪一块中
3、在已确定的块中用顺序法进行查找
实现
#include<stdio.h>
struct number{ //定义块的结构
int key;
int start;
int end;
}array_table[4];
int blocks_search(int a[],int num)
{
int i,j;
i=0;
while(num>array_table[i].key && i<4)
i++;
if(i>=4)
return 0;
j=array_table[i].start;
for(;num!=a[j] && j<=array_table[i].end;j++);
if(j>array_table[i].end)
j=0;
return j;
}
int main()
{
int i,j,key,a[16];
j=0;
printf("please input the number:\n");
for(i=1;i<16;i++)
scanf("%d",&a[i]);
for(i=1;i<=3;i++){
array_table[i].start=j+1;//确定每个块范围的起始值
j=j+1;
array_table[i].end=j+4; //确定每个块范围的结束值
j=j+4;
array_table[i].key=a[j]; //确定每个块范围中元素的最大值
}
printf("please input the number which do you want to search:\n");
scanf("%d",&key);
k=blocks_search(key,a);
if(k!=0)
printf("success the position is:%d\n",k);
else
printf("no found!");
}
三、哈希表
哈希表查找是先利用哈希表存储元素,再利用哈希特性进行查找的一种方法。原理
使用一个下标范围比较大的数组来存储元素。设计一个哈希(散列)函数,使得每个元素的关键字都与一个函数值(即数组下标)相对应,于是用这个数组单元来存储这个元素;简单理解为按照关键字为每一个元素“分类”,然后将这个元素存储在相应“类”所对应的地方。
函数构造
设h(k)表示关键字k的元素所对应的函数值。
1、除余法:
选择一个正整数p,令h(k)=k mod p。这里p选取的是较大的素数比较好。
2、如果关键字的位数比较多,超过长整型范围而无法直接运算,可以选择其中数字分布比较均匀的若干位,所组成的新的值作为关键字或者直接作为函数值。
实现
typedef struct ListNode{
const char *value;
struct ListNode *next;
}ListNode;
typedef struct HashTable{
struct ListNode **list;
int tableSize;
}HashTable;
ListNode* Find(const char *key,HashTable* H)
{
ListNode* p;
ListNode* L;
L=H->list[hash(key,H->tableSize)];
p=L->next;
while(p!=NULL && p->value!=key)
p=p->next;
return p;
}
void Insert(const char *key,HashTable* H)
{
ListNode* p,*temp;
ListNode* L;
p=Find(key,H);
if(p==NULL){
temp=(ListNode*)malloc(sizeof(ListNode));
if(temp==NULL)
printf("out of space");
else{
L=H->list[hash(key,H->tableSize)];
temp->next=L->next;
temp->value=key;
L->next=temp;
}
}
}
四、二分搜索
二分查找也称折半查找(Binary Search),是一种效率较高的查找方法。但是,二分查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
实现
int binary_search(int a[],int target,int n)
{
int low,high,mid;
low=0,high=n;
while(low<=high){
mid=low+(high-low)/2;
if(a[mid]<target)
low=mid+1;
if(a[mid]>=target)
high==mid-1;
}
return low;
}
五、二分搜索树
通常用平衡树实现C++标准模板库中的set模板。