####查找算法学习
#####顺序查找
- 最简单的查找方法,从线性表的一端开始,依次将每个记录的关键字进行比较,若相同则返回该关键字所在数组的位置
int SeqSearch(int A[],int n,int key){
int i ;
for(i = 0;i<n;i++){
if(A[i] == key){
return i;
//返回当前位置
}
}
return -1;
}
int main(int argc, const char * argv[]) {
int A[10] = {1,2,3,4,5,6,7,8,9,0};
int data = SeqSearch(A,10, 0);
printf("%d",data);
return 0;
}
#####折半查找(二分查找)
折半查找要求查找表的数据是线性结构保存,并且还要求查找表的数据是按照关键字由小到大有序排列
int BinarySearch(int A[],int n,int key){
int low,high,mid;
low = 0;high = n-1;
while(low<=high){
mid = (low+high)/2;
if(A[mid]==key){
//如果中间的值恰好等于关键字的值,则返回
return mid;
}else if(A[mid]>key)
//如果中间值大于关键字
high = mid -1;
//最大的值为中间值 -1
else
low = mid +1;
// 最小的值为中间值
}
return -1;
}
int main(int argc, const char * argv[]) {
int A[10] = {1,2,3,4,5,6,7,8,9,0};
int data = BinarySearch(A, 10, 3);
printf("%d",data);
}
#####索引查找
- 在大批量的数据进行查找时,查找效率不高.为了提高查找效率,可首先对大批量的数据针对关键字创建一个索引.
- 索引的特点:提高数据查找的速度,缺点是需要占用一定的磁盘空间,另外索引减慢了数据插入和删除的速度
#define TABLE_LEN 30 //主表长度
#define INDEXTABLE_LEN 3 //索引表长度
typedef struct item{
int index; //索引值
int start; //开始位置
int length; //子表长度
}INDEXITEM;
/*定义主表数据*/
long stu[TABLE_LEN] = {
1080101,1080102,1080103,1080104,1080105,1080106,0,0,0,0,
1080201,1080202,1080203,1080204,0,0,0,0,0,0,
1080301,1080302,1080303,1080304,0,0,0,0,0,0
};
/* 定义索引表*/
INDEXITEM indextable[INDEXTABLE_LEN] = {
{10801,0,6},
{10802,10,4},
{10803,20,4}
};
/* 查找*/
int IndexSearch(int key){
int i,index1,start,length;
index1 = key/100;
for(i = 0;i<INDEXTABLE_LEN;i++){
if(indextable[i].index==index1){
//如果在索引表中找到了
start = indextable[i].start;
//获得数据初始长度
length = indextable[i].length;
//获得该索引数据结束长度
break;
}
}
if(i>=INDEXTABLE_LEN){
return -1;
}
for(i = start;i<start+length;i++){
//在该索引范围查找key 值
if(stu[i] == key){
return i ;
}
}
return - 1;
}
/*插入索引*/
int InsertNode(key){
int i,index1,start,length;
index1 = key/100;
for(i = 0;i<INDEXTABLE_LEN;i++){
if(indextable[i].index==index1){
//如果在索引表中找到了
start = indextable[i].start;
//获得数据初始长度
length = indextable[i].length;
//获得该索引数据结束长度
break;
}
}
if(i>=INDEXTABLE_LEN) return -1;
stu[start+length] = key;
indextable[i].length++;
return 0 ;
}
int main(int argc, const char * argv[]) {
// insert code here...
int key = 1080202;
int pos = IndexSearch(key);
printf("%d",pos);
return 0;
}
#####散列表 method:以线性表每个元素的关键字key为自变量,通过一定的函数关系h(key)计算出函数的值
- 构造散列表函数
- 1,直接定址法:以关键字key本身或关键字key加上某个常数C,用来作为散列地址
- 2,除数取余法:用关键字key除以散列表长度n,得到的余数作为散列地址(最好将其值取一个素数)
- 3,数字分析法:取关键字中某些比较分散的数字作为散列地址的方法.适用于关键字已知
- 4,平方取中法:将关键字key求平方后,取中间的几位数字作为散列地址的方法
处理冲突
- 开放地址法:从发生冲突的那个数组元素开始,按一定的次序,从散列表中查出一个空闲的元素数组,把发生冲突的待插入元素存入该数组元素中
- 链接法:在散列表的每个存储单元增设一个指针域,将散列地址相同的元素链接起来
#define HASH_LEN 13
#define TABLE_LEN 8
int data[TABLE_LEN] = {69,65,90,37,92,6,28,54};
//原始数据
int hash[HASH_LEN] = {0};
//散列表 初始化为0
void InsertHash(int hash[],int m,int data){
//参数hash为散列表的首地址,参数M为散列表长度,参数data为需要添加到散列表的关键字
int i;
i = data % 13;
while(hash[i])
//若已经被使用,则使用线性探测法查找下一个开放地址
i = (++i) % m;
hash[i] = data;
}
/* 创建散列表*/
void CreateHash(int hash[],int m,int data[],int n){
int i ;
for(i = 0;i<n;i++){
InsertHash(hash, m, data[i]);
}
}
/*进行hash 搜索*/
int HashSearch(int hash[],int m,int key){
int i;
i = key % 13;
while(hash[i]&&hash[i]!=key)
i = (++i) % m ;
if(hash[i]==0){
return -1;
}else
return i;
}
int main(int argc, const char * argv[]) {
// insert code here...
CreateHash(hash, HASH_LEN, data, TABLE_LEN);
for(int i = 0;i<HASH_LEN;i++){
printf("%d ",hash[i]);
}
int pos = HashSearch(hash, HASH_LEN, 54);
printf("%d",pos);
printf("Hello, World!\n");
return 0;
}
来源:oschina
链接:https://my.oschina.net/u/2380832/blog/616809