数据结构(C语言版)---查找
1、查找表:同一类型的数据元素构成的集合。
2、对查找表进行的操作:查询某特定元素、检索满足条件的元素的属性、插入元素、删除元素。
1)若对查找表进行的操作只涉及前两种,则为静态查找表;需要进行插入和删除,则为动态查找表。
2)适合静态查找表的查找方法:顺序查找、折半查找、散列查找。
3)适合动态查找表的查找方法:二叉排序树(二叉平衡树和B树都是二叉排序树的改进)的查找、散列查找。
3、顺序查找(线性查找):用于在线性表中进行查找。
1)一般线性查找表的顺序查找
(1)对于n个元素的表,查找成功的平均查找长度为ASL成功=Pi(n-i-+1),(从1到N求和)。
(2)当每个元素查找概率相等时,即Pi=1/n,ASL成功=(n+1)/2,ASL失败=n+1。
2)有序表的顺序查找
查找成功的平均查找长度和一般线性查找表的顺序查找一样;查找不成功时ASL失败=n/2+n/(n+1)。
3)一般线性表的存储结构描述
typedef struct {
int * elem;//基地址
int tablelen;//表的长度
}SSTable;
4)在顺序表ST中顺序查找关键字为key的元素
int Seqsearch(SSTable ST, int key)
{
ST.elem[0] = key;
int i;
for ( i = ST.tablelen; ST.elem[i] != key; --i);
return i;
}
5)顺序查找表,找到后和其前面的元素交换
int Seqsrch(SSTable r, int k)
{
int i = 0, temp;
while ((r.elem[i]!=k)&&(i<r.tablelen))
{
i++;
}
if (i < r.tablelen&&i>0)
{
temp = r.elem[i];
r.elem[i] = r.elem[i - 1];
r.elem[i - 1] = temp;
return --i;
}
else
{
return -1;
}
}
4、折半查找(二分查找):仅适用于有序的顺序表。
1)折半查找的过程用二叉树描述,称为判定树。
(1)若有序序列有n个元素,则对应的判定树有n个圆形的非叶结点和n+1个方形叶结点。
(2)当元素个数为n时,树的高度为h=log2(n+1)。
2)查找成功的平均查找长度:ASL成功=log2(n+1)-1,折半查找的时间复杂度为O(log2n)。
3)折半查找的存储结构必须具有随即存取的特性。
4)折半查找---在有序表L中查找关键字为key的元素
int binarysearch(SSTable L, int key)
{
int low = 0, high = L.tablelen - 1, mid;
while (low <= high)
{
mid = (low + high) / 2;
if (L.elem[mid] == key)
{
return mid;
}
else if (L.elem[mid] > key)
{
high = mid - 1;
}
else
{
low = mid + 1;
}
}
return -1;
}
5、有序表的顺序查找和折半查找的区别:有序表的顺序查找中的线性表可以为链式存储结构。
6、分块查找(索引顺序查找)
1)操作:将查找表分成若干块,块内无序,块间有序。
2)将长度为n的查找表均匀的分为b块,每块有s个记录,在等概率情况下:
(1)若在块内和索引表中均采用顺序查找,则平均查找长度为ASL=(b+1)/2+(s+1)/2=(s2+2s+n)/2s;
(2)若s=√n,则平均查找长度取最小值√n+1。
(3)若对索引表采用折半查找,则平均查找长度为ASL=log2(b+1)+(s+1)/2。
7、B树:所有结点的平衡因子均等于0的多路平衡查找树。
1)B树的阶:B树中所有结点的孩子结点数的最大值。
2)m阶B树的性质:
(1)每个结点至多有m棵子树,即至多含有n-1个关键字;
(2)若根结点不是终端节点,则至少有两棵子树;
(3)除根结点外的所有非叶结点至少有m/2棵子树,即至少含有m/2-1个关键字;
(4)非叶结点的结构
| n(结点中关键字的个数) | p0 | k1 | p1 | k2 | p2 | ... | kn | pn |
其中,ki为结点的关键字,且k1<k2<...<kn,pi为指向子树根结点的指针,且pi-1所指子树中所有结点的关键字均小于ki,pi所指子树中所有结点的关键字均大于ki;
(5)所有叶结点都出现在同一层次上。
3)B树的高度
若n>=1,则对于任意一棵包含n个关键字、高度为h、阶数为m的B树
(1)h>=logm(n+1);
(2)若让每个结点中的关键字个数达到最少,则容纳同样多关键字的B树的高度达到最大。
4)B树的查找
基本操作:在B树中找结点,在结点内找关键字。
5)B树的插入
(1)定位:找出插入该关键字的最底层中的某个非叶结点。(B树中的插入关键字一定插入在最底层中的某个非叶结点内)
(2)插入:每个非失败结点的关键字个时速都在区间[m/2-1,m-1]内,
插入后的结点关键字个数小于m,可以直接插入;插入后的结点关键字个数大于m-1,必须对结点进行分裂。
6)B树的删除
(1)删除非终端结点时
若小于k的子树中关键字个数>m/2-1,则找出k的前驱值,并用k的前驱值取代k,再递归删除前驱。
若大于k的子树中关键字个数>m/2-1,则找出k的后继值,并用k的后继值取代k,再递归删除后继。
若前后两个子树中关键字个数均为m/2-1,则直接将两个子节点合并,直接删除k。
(2)删除终端结点时
直接删除关键字。若被删除关键字所在结点的关键字个数>m/2-1,直接删除。
兄弟够借。若被删除关键字所在节点删除前的关键字个数=m/2-1,且与此结点相邻的右(左)兄弟结点的关键字个数>=m/2-1,则调整该结点的兄弟结点及双亲结点,达到平衡。
兄弟不够借。若被删除关键字所在节点删除前的关键字个数=m/2-1,且与此结点相邻的右(左)兄弟结点的关键字个数=m/2-1,则将该结点的兄弟结点及双亲结点中的关键字进行合并。
8、B+树
1)m阶B+树的性质:
(1)每个分支结点最多有m棵子树;
(2)非叶根结点至少有两棵子树,其他每个分支结点至少有m/2棵子树;
(3)结点的子树个数与关键字个数相等;
(4)所有叶结点包含全部关键字及指向相应记录的指针,叶结点中将关键字按大小顺序排列,并且相邻叶结点按大小顺序互相链接起来;
(5)所有分支节点中仅包含它的各个子结点中关键字的最大值及指向其子结点的指针。
8、B树和B+树的区别
1)B+树中,n个关键字的结点只含有n棵子树,即每个关键字对应一颗子树;B树中,n个关键字的结点含有n+1棵子树。
2)B+树中,每个结点的关键字个数n的范围m/2<=n<=m,根结点1<=n<=m;B树中,每个结点的关键字个数n的范围m/2-1<=n<=m-1,根结点1<=n<=m-1。
3)B+树中,叶结点包含信息,非叶结点仅起索引作用,非叶结点中的每个索引项只含有对应子树的最大关键字和指向该子树的指针,不含有该关键字对应记录的存储地址。
4)B+树中,叶结点包含了全部关键字,即在非叶结点中出现的关键字也会出现在叶结点中;B树中,叶结点包含的关键字和其他结点包含的关键字是不重复的。
9、散列表:根据关键字而直接进行访问的数据结构。
散列函数:一个把查找表中的关键字映射陈该关键字对应的地址的函数,记作Hash(key)=Addr。
冲突:散列函数将两个或两个以上的不同关键字映射到同一个地址。
散列表建立了关键字和存储地址之间的一种直接映射关系。
10、常用的散列函数
1)直接定址法
直接取关键字的某个线性函数值为散列地址,散列函数为H(key)=a*key+b,ab为常数。
适合关键字的分布基本连续的情况,不会产生冲突。
2)除留余数法
假定散列表的表长为m,取一个不大于m但最接近或等于m的质数p,散列函数为H(key)=key%p。
3)数字分析法
4)平方取中法
5)折叠法
11、处理冲突的方法
假定选定散列函数H(key),Hi表示发生冲突后第i次探测的散列地址。
1)开放定址法:指可存放新表项的空闲地址既向它的同义词表项开放,又向它的非同义词表项开放。Ni=(H(key)+di)%m,(m表示散列表表长,di为增量序列)。
当某一增量序列确定后,对应处理方法确定,通常有4种:线性探测法、平方探测法、再散列法、伪随机序列法。
2)拉链法(链接法)
12、散列表的查找效率取决于三个因素:散列函数、处理冲突的方法、装填因子。
装填因子:一个表的装满程度。α=表中记录数n/散列表长度m。α,发生冲突的可能性越大。
数据结构(C语言版)---查找的更多相关文章
- 数据结构C语言版 有向图的十字链表存储表示和实现
/*1wangxiaobo@163.com 数据结构C语言版 有向图的十字链表存储表示和实现 P165 编译环境:Dev-C++ 4.9.9.2 */ #include <stdio.h> ...
- c++学习书籍推荐《清华大学计算机系列教材:数据结构(C++语言版)(第3版)》下载
百度云及其他网盘下载地址:点我 编辑推荐 <清华大学计算机系列教材:数据结构(C++语言版)(第3版)>习题解析涵盖验证型.拓展型.反思型.实践型和研究型习题,总计290余道大题.525道 ...
- 数据结构C语言版 表插入排序 静态表
数据结构C语言版 表插入排序.txt两个人吵架,先说对不起的人,并不是认输了,并不是原谅了.他只是比对方更珍惜这份感情./* 数据结构C语言版 表插入排序 算法10.3 P267-P270 编译 ...
- 数据结构C语言版 弗洛伊德算法实现
/* 数据结构C语言版 弗洛伊德算法 P191 编译环境:Dev-C++ 4.9.9.2 */ #include <stdio.h>#include <limits.h> # ...
- 《数据结构-C语言版》(严蔚敏,吴伟民版)课本源码+习题集解析使用说明
<数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+习题集解析使用说明 先附上文档归类目录: 课本源码合辑 链接☛☛☛ <数据结构>课本源码合辑 习题集全解析 链接☛☛☛ ...
- 深入浅出数据结构C语言版(12)——从二分查找到二叉树
在很多有关数据结构和算法的书籍或文章中,作者往往是介绍完了什么是树后就直入主题的谈什么是二叉树balabala的.但我今天决定不按这个套路来.我个人觉得,一个东西或者说一种技术存在总该有一定的道理,不 ...
- 深入浅出数据结构C语言版(5)——链表的操作
上一次我们从什么是表一直讲到了链表该怎么实现的想法上:http://www.cnblogs.com/mm93/p/6574912.html 而这一次我们就要实现所说的承诺,即实现链表应有的操作(至于游 ...
- 【数据结构(C语言版)系列二】 栈
栈和队列是两种重要的线性结构.从数据结构角度看,栈和队列也是线性表,但它们是操作受限的线性表,因此,可称为限定性的数据结构.但从数据类型角度看,它们是和线性表大不相同的两类重要的抽象数据类型. 栈的定 ...
- 深入浅出数据结构C语言版(6)——游标数组及其实现
在前两次博文中,我们由表讲到数组,然后又由数组的缺陷提出了指针式链表(即http://www.cnblogs.com/mm93/p/6576765.html中讲解的带有next指针的链表).但是指针式 ...
- 深入浅出数据结构C语言版(8)——后缀表达式、栈与四则运算计算器
在深入浅出数据结构(7)的末尾,我们提到了栈可以用于实现计算器,并且我们给出了存储表达式的数据结构(结构体及该结构体组成的数组),如下: //SIZE用于多个场合,如栈的大小.表达式数组的大小 #de ...
随机推荐
- 【tensorflow2.0】处理结构化数据-titanic生存预测
1.准备数据 import numpy as np import pandas as pd import matplotlib.pyplot as plt import tensorflow as t ...
- 基于Java的数字货币交易系统的架构设计与开发
前言 无论是股票交易系统,还是数字货币交易系统,都离不开撮合交易引擎,这是交易平台的心脏.同时,一个优秀的架构设计也会让交易平台的运维和持续开发更加容易.本文基于对开源项目的深入研究,总结了数字货币交 ...
- A 修公路
时间限制 : - MS 空间限制 : 65536 KB 评测说明 : 时限1000ms 问题描述 某岛国有n个小岛构成(编号1到n),该国政府想要通过n-1条双向公路将这些小岛连接起来,使得任意 ...
- Educational Codeforces Round 84 (Rated for Div. 2)
A. Sum of Odd Integers(思维) 思路 这一题看完ans之后觉得是真简单,不过有一些地方还是要理解的. 这一题输出YES,有两个条件 kk%2 == n%2k,这个条件的意思是 k ...
- java 第六周上机练习 04.09
1.编写一个简单程序,要求数组长度为5,静态赋值10,20,30,40,50,在控制台输出该数组的值. int [] arr= {10,20,30,40,50}; for(int i=0;i<a ...
- 力软敏捷框架 jfGrid 使用例子之一
百度了下关于力软敏捷框架 jfGrid的教程,基本没有,出来的全是jqGrid.好吧看来只能自己上手了 今天来讲讲列设置属性里数据格式化事件(formatter)的使用 常规的使用方式如上图所示. 先 ...
- Spark Streaming 编程入门指南
Spark Streaming 是核心Spark API的扩展,可实现实时数据流的可伸缩,高吞吐量,容错流处理.可以从许多数据源(例如Kafka,Flume,Kinesis或TCP sockets)中 ...
- Func 和 Action 委托
有了泛型委托,就有了一能适用于任何返回类型和任意参数(类型和合理的个数)的通用委托,Func 和 Action.如下所示(下面的in表示参数,out表示返回结果): delegate TResult ...
- 理解 Hanoi 汉诺塔非递归算法
汉诺塔介绍: 汉诺塔(港台:河内塔)是根据一个传说形成的数学问题: 最早发明这个问题的人是法国数学家爱德华·卢卡斯. 传说越南河内某间寺院有三根银棒,上串 64 个金盘.寺院里的僧侣依照一个古老的预言 ...
- Hadoop(五):HDFS的JAVA API基本操作
HDFS的JAVA API操作 HDFS在生产应用中主要是客户端的开发,其核心步骤是从HDFS提供的api中构造一个HDFS的访问客户端对象,然后通过该客户端对象操作(增删改查)HDFS上的文件. 主 ...