常用查找算法

一、顺序搜索

       顺序查找是在一个已知无(或有)序队列中找出与给定关键字相同的数的具体位置。顺序查找适合小规模的数据
原理
从序列的第一个元素开始,依次与关键字进行比较,直到找到目标关键字或者查找失败。
    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模板。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值