查找——顺序查找、二分查找、散列查找

顺序查找

适用于:顺序表、链表
代码展示
/*  
* 第一种
* */
int search(int a[], int n, int key)
{
	int i;
	for(i = 0; i < n; i ++)
		if(a[i] == key)
			break;
	if(i == n) return -1;
	else return 1;
}
/*  
* 第二种
* */
int search(int a[], int n, int key)
{
	int i;
	for(i = 0; i < n && a[i] != key; i ++);
	
	if(i == n) return -1;
	else return 1;
}
/*  
* 第三种
* */
int search(int a[], int n, int key)
{
	int i, tag = -1;
	for(i = 0; i < n; i ++)
		if(a[i] == key)
		{
			tag = i;
			break:
		}
	return tag;
}

二分查找

条件1:经过排序的数据集合
条件2:只适合于顺序存储的数据结构

设有数据集合 {5,13,17,42,46,55,70,94}

元素513174246557094
下标01234567
表示lowhigh

查找94
(0+7 )/ 2 = 3 ----> a[3] < key
(4+7) / 2 = 5 ----> a[5] < key
(6+7) / 2 = 6 ----> a[6] < key
(7+7) / 2 = 7 ----> a[7] = key ----> win

查找5
(0+7) / 2 = 3 ----> a[3] > key
(0+2) / 2 = 1 ----> a[1] > key
(0+0) / 2 = 0 ----> a[0] = key ----> win

引入到树——二叉树

时间复杂度 log2n

结论:二分查找会生成一棵二叉查找树

上左下右

42
13
55
5
17
46
70
94

mid = (low+high) / 2 —> a[mid] < key —> low = mid + 1
else
mid = (low+high) / 2 —> a[mid] > key —> high = mid - 1

(针对递归代码)结束条件 low > high
循环实现
/*
*  二分查找
*/
int HalfSearch(int a[], int low, int high, int key)
{
	int mid;
	while(low <= high)
	{
		mid = (low + high) / 2;
		if (a[mid] = key)
			return mid;
		else if(a[mid] < key)
			low = mid + 1;
		else
			high = mid - 1;
	}
	return -1;
}

散列查找(哈希查找)

  • 设有一长度为m的散列空间
  • 将某一个数据集合中的数据存储在散列空间中
散列函数H(K):
  • 用来计算存储数据元素的地址的函数
  • H(K) = K%M (除留余法)
  • 设散列空间长度 13
  • 有数据集合 { 5,13,17,42,44 }
  • 采用除留余法存储数据集合
  • 散列函数 H(k) = k %13
  • 5%13 == 5
  • 13%13 == 0
  • 17%13 == 4
  • 42%13==3
  • 45%13 == 6
元素
下标012345678910111213
函数13%13 == 042%13==317%13 == 45%13 == 545%13 == 6

缺陷

  • 容易造成堆积
  • 产生冲突
    同义词冲突:两个以上的数据元素要占据同一个地址单元。

解决冲突

开放定址法—线性勘查法
  • d = (d+1) % m
拉链法
  • 把所有冲突元素放在一条链表上边

练习

  • 散列长度 13
  • 数据集合 { 5,13,17,42,46,55,70,82,94 }
  • 5%13=5
  • 13%13=0
  • 17%13=4
  • 42%13 =3
  • 46%13=7
  • 55%13=3 、4、5、6
  • 70%13=5、6、7、8
  • 82%13=4、5、6、7、8、9
  • 94%13=3、4、5、6、7、8、9、10
  • 平均查找长度:
    ASC = (15 + 42 + 6 + 8)/ 9

  • (拉链法)ASL = (15+ 23+3)/ 9

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值