当前位置: 首页 > article >正文

Day 11-12:查找

目录

概念

方法

折半查找   

        前提

        算法思路

分块查找

        算法思路

哈希表 

         概念

        构造哈希函数的方法

        保留除数法

        处理冲突的方法

                开放地址法(二次探查法)

                链地址法(重要) 

 哈希表的实现

        结构体的创建

        哈希表的创建         

        哈希元素插入 

        哈希元素查找

概念

        记录表L=(R1 R2……Rn),其中Ri(l≤i≤n)为记录,对给定的某个值k,在表L中确定key=k的记录的过程,称为查找

        表L中存在一个记录Ri的key=k,记为Ri.key=k,则查找成功,返回该记录在表L中的序号i(或Ri 的地址),否则(查找失败)返回0(或空地址Null)。

方法

      顺序查找、折半查找、分块查找、Hash表。      

折半查找   

        前提

        仅仅适用于有序的顺表。

        算法思路

        首先将给定值key与表中中间位置的元素(mid的指向元素)比较。mid=low+high/2(向下取整)

        若key与中间元素相等,则查找成功,返回该元素的存储位置,即mid;
        若key与中间元素不相等,则所需查找的元素只能在中间元素以外的前半部分或后半部分。(至于是前半部分还是后半部分要看key与mid所指向元素的大小关系)
        a.若给定值key大于中间元素则所查找的元素只可能在后半部分。此时让low=mid+1;
        b.若给定值key小于中间元素则所查找的元素只可能在前半部分。此时让high=mid-1;

        举例:查找key = 20

分块查找

        算法思路

  1. 需要把数据分成N多小块,块与块之间不能有数据重复的交集。

  2. 给每一块创建对象单独存储到数组当中。

  3. 查找数据的时候,先在数组查,当前数据属于哪一块。

  4. 再到这一块中顺序查找。

哈希表 

         概念

        对给定的k,不经任何比较便能获取所需的记录,其查找的时间复杂度为常数级O(C)。在建立记录表的时候,确定记录的key与其存储地址之间的关系f,即:

        使key与记录的存放地址H相对应。

        这个关系f就是所谓的Hash函数(或称散列函数、杂凑函数),记为H(key)。 

        构造哈希函数的方法

        保留除数法

        概念:设Hash表空间长度为m,选取一个不大于m的最大质数p。

        H(key) = key % p

         

         冲突:表中某地址j∈[0,m-1]中己存放有记录,而另一个记录的H(key)值也为 j。

        表的装填因子α:α=n/m,其中m为表长,n为表中记录个数。一般α在0.7~0.8之间,使表保持一定的空闲余量,以减少冲突和聚积现象。比如:有70%的数据要存,选择一个数组长度为100%的数组来存。

        质数的选取:不大于m的最大质数。            

        处理冲突的方法

        在地址j的前面或后面找一个空闲单元存放冲突的记录,或将相冲突的诸记录拉成链表。


                开放地址法(二次探查法)

        当发生冲突时,在H(key)的前后找一个空闲单元来存放冲突的记录,即在H(key)的基础上获取下一地址: 

        Hi=(H(key)+di)%m

        其中m为表长,%运算是保证Hi落在[0,m-l]区间

        di为地址增量。di的取法有多种:    

        (1)di=1,2,3,……(m-1)——称为线性探查法;    

        (2)d = 1^2, -1^2, 2^2, -2^2, 3^2,……

        举例

        设记录的key集合k={23,34,14,38,46,16,68,15,07,31,26},记录数n=11。

        令装填因子α=0.75,取表长m= n/α =15。 用“保留余数法”选取Hash函数(p=13):                  H(key)=key%13

         16 % 13 == 68 % 13

         46 % 13 == 7   % 13


                链地址法(重要) 

        发生冲突时,将各冲突记录链在一起,即同义词的记录存于同一链表。

        设H(key)取值范围(值域)为[0,m-l], 建立头指针向量HP[m], HP[i](0≤i≤m-l)初值为空。 

 哈希表的实现

        结构体的创建

#define M 15//表长
typedef int datatype;
/*1.创建链表结构体*/
typedef struct node
{
	datatype key;
	datatype value;
	struct node* next;
}listnode,*linknode;
/*创建链表数组,存放链表的头节点*/
typedef struct
{
	listnode data[M];
}hash,*linkhash;

        哈希表的创建         

/*哈希表创建*/
linkhash hash_create()
{
	linkhash HT;
	if (HT = malloc(sizeof(hash)) == NULL)
	{
		printf("create failed!\n");
		return NULL;
	}
	memset(HT, 0, sizeof(hash));
	return HT;
}

        哈希元素插入 

/*哈希元素插入*/
/*整体逻辑:1.求余数 2.判断是否冲突(原来有值)*/
int hash_insert(linkhash HT, datatype value)
/*注意:结构体数组上仅存放了指向第一个数的指针*/
{
	linknode p,q;
	if (HT == NULL)
		return -1;
	/*1.创建一个链表存放插入值:指针p*/
	if ((p = malloc(sizeof(listnode)) == NULL)
		return -1;
	p->key	 = value % P;
	p->value = value; 
	p->next  = NULL;
	/*2.找到数组上对应的位置,判断是否为冲突元素?否则就是空元素(?),指针q*/
	q = &(HT->data[value % P]);
	/*移动q指针,目标:越大越放在后面*/
	while (q->next != NULL && q->next->value < p->value)
	{
		q = q->next;
	}
	/*3.插入元素并要注意链表插入规则,以在16和68之间为例*/
	p->next = q->next;
	q->next = p;
	return 0;
}

        哈希元素查找

/*哈希查找*/
linknode hash_search(linkhash HT, datatype value)
{
	if (HT == NULL)
		return -1;
	linknode p;
	p = &HT->data[value % P];
	while (p->next &&  p->next->value != value)
	{
		p = p->next;
	}
	if (p->next == NULL)
		return NULL;
	else
		return p->next;
}

 

 

        

         

 

        

        

        

        

        


http://www.kler.cn/news/303191.html

相关文章:

  • day14-单例设计模式动态代理
  • Qt 学习第八天:菜单栏、工具栏、状态栏、模态和非模态对话框创建
  • RabbitMQ延迟消息——DelayExchange插件
  • Python之 条件与循环(Python‘s Conditions and loops)
  • 在麒麟系统 v10 SP3 上运行自带的 MariaDB
  • 【鸿蒙】HarmonyOS NEXT星河入门到实战6-组件化开发-样式结构重用常见组件
  • Oracle中VARCHAR和VARCHAR2的区别
  • CSS框架 Tailwind CSS
  • Leetcode3276. 选择矩阵中单元格的最大得分
  • CNN中的conv
  • ASP.net core 8.0网站发布
  • 房产销售系统|基于java和vue的房产销售系统(源码+数据库+文档)
  • 利用apache-pdfbox库修改pdf文件模板,进行信息替换
  • 【基础算法总结】二分查找
  • 在Python的Pandas库中,`df.iloc[::500]`是一个用于数据选择的索引器,它允许我们从DataFrame中选择特定的行和列。
  • golang学习笔记19——golang做服务发现与注册的深度剖析
  • 从安装ffmpeg开始,把一个视频按照每秒30帧fps剪切为图片
  • Vue组件:模板引用ref属性的使用
  • 微信小程序之轮播图组件封装
  • CTF常见编码及加解密(超全)第二篇
  • java程序员入行科目一之CRUD轻松入门教程(二)
  • layui监听table表单的多选框
  • 高级实时通信:基于 Python 的 WebSocket 实现与异步推送解决方案
  • 商务办公tips1:如何将网页转换为pdf
  • Python 数学建模——Vikor 多标准决策方法
  • 基于react native的锚点
  • 鼎捷新一代PLM 荣膺维科杯 “2023年度行业优秀产品奖”
  • 基于Service Worker实现WebRTC局域网大文件传输能力
  • C语言可变参数函数和可变参数宏
  • Python 数学建模——方差分析