数据结构---查找

1.查找的相关概念

查找:在n个记录里,寻找关键字等于目标k的过程,唯一匹配数据数据元素的数据项称为主关键字,其余数据项称为次关键字。

平均查找长度:反映统计意义上的多次查找的平均查找长度。

查找的方法:线性查找

2.线性查找(顺序查找)

从记录起始开始,逐个匹配记录信息,直到寻到目标关键字,若到最后仍未有相关信息,进行提示输出。

//顺序查找
int SeqSearch(int r[],int n,int k)
{
	r[n].key=k; //目标信息
        i=0;
	while (r[i].key!=k)  //关键字匹配
              i++;
	return(i);
}
说明:若返回n表明查找不成功。
链式存储结构:
{
 p=h->next;
 while ((p!=NULL) && (p->key!=k)) p=p->next; 
 return  p;
}

  性能分析:

3.对分查找(拆半查找)

针对有序表的一种查找方式,先比较中间记录关键字信息,若匹配则输出,大于中间记录,则查找后半区间,若小于中间记录,则查找上半区间,由此递归查询,直到获得匹配信息。

对分查找
int BinSearch(int r[],int n,int k)
{
	int low=0,hig=n-1;
	while (low<=hig){
		mid=(low+hig)/2; //中间记录
		if (k==r[mid]) return(1);
		if (k<r[mid]) hig=mid-1;
		if (k>r[mid]) low=mid+1;
	}
	return(0);
}

  性能分析:ASL = log2(n+1) + 1

优点是平均查找长度小,但是需要是顺序表,适用于建立后不需要多加改变同时需要大量查找操作的顺序表。

4.分块查找(索引顺序查找)

把所有关键字分块,并且后面的关键字的值均大于前一块,快内的关键字保持无序。查找过程是先使用顺序查找或对分查找确定关键字块,再在块内进行顺序查找。性能介于顺序查找和对分查找之间。

5.二叉排序树查找

将待查信息与根节点关键字进行比较,匹配则输出,小于则进入左子树,大于则进入右子树,依次循环查找。

int BstSearch(NODE *t,int k)
{
 if (t){ 
	if (k==p->data) return(1); //根节点
	if (k<p->data) BstSearch(t->lchild,k);//查找左子树
	if (k>p->data) BstSearch(t->rchild,k);//查找右子树
 }
 else return(0);
}

  性能分析:与二叉排序树结构相关,最好情况下,为均匀的二叉树,平均查找长度与二分查找相近,为log2n,最坏情况为单子树,平均查找长度为(n+1)/2。

6.哈希查找

通过对给定值进行一定运算,直接求得与指定值信息匹配的关键字的位置。

哈希函数、哈希地址、哈希表、装填系数(a=n/m,一般为0.65-0.85)、非数值关键字的内部码、冲突(不同关键字的系统哈希地址)、同义词

6.1哈希查找的几种技术

6.1.1数字分析法

适合静态数据,关键字已知,分析数字的分布,删除不均匀的数字,再根据存储空间决定数字的数目。

6.1.2平方取中法

关键字平方,选取其中几位作为哈希地址

6.1.3除留余数法

对关键字取模(余数)作为哈希地址

6.1.4折叠法

将关键字拆分成几段,除了最后一段每段长度均相等,再将各段相加作为哈希地址。包括移位折叠(字段左靠齐后相加)和边界折叠(偶数字段倒排,最后字段右考)两种。

6.2解决冲突的方法

6.2.1线性探测再散列

线性表空间为T[m],哈希函数为H,冲突时另一个记录的地址公式为 dj+1=(d1+j) % m  (j=1,2,…,s,s≥1),其中d1=H(key)。即在冲突时,以线性的方式从下一个哈希地址开始探测,直到查到下一个空的存储地址。若一个循环还没有找到空间,说明地址已满。

LineSearch(T,k,m)
{
	i=H(k); j=i;
	while (T[j].key!=k && T[j].key!=0){
		j=(j+1)%m;
		if (j==i){ 表满;return(-1);}
	}
	return(j);
}

  缺点:易造成关键字聚集,增加查找时间。

6.2.2平方探测再散列

改善线性探测的缺点,避免关键字的聚集。

6.2.3随机探测再散列

用一组预先给定的随机数求冲突时的地址,公式为: dj=(d1+Rj) % m   (j=1,2,...,s,s≥1)   其中Rj为一组随机数列。

6.2.4链地址法

在哈希表中设置一个由m个指针分量组成的一位数组,凡哈希地址为i的记录都插入到头指针为ST[i]的链表中,适用于造表前无法确定记录个数的情况。 

ChnSearch(ST,m,k)
{
	i=H(k);  p=ST[i];
	while (p && p->data!=k) p=p->next;
	return(p);
}

  

原文地址:https://www.cnblogs.com/zouhq/p/10615054.html