算法与数据结构(c语言)第6章集合与字典.ppt
《算法与数据结构(c语言)第6章集合与字典.ppt》由会员分享,可在线阅读,更多相关《算法与数据结构(c语言)第6章集合与字典.ppt(73页珍藏版)》请在三一办公上搜索。
1、第六章 集合与字典,从逻辑结构上看,集合和字典都是最简单的数据结构,它们的元素之间没有任何确定的依赖关系。字典是关联的集合。作为抽象数据类型,集合和字典之间的主要区别,在于它们的操作。集合主要考虑集合之间的并、交和差操作;字典主要关心其元素的检索、插入和删除。,目录,6.1集合及其抽象数据类型 基本概念 主要运算 抽象数据类型6.2集合的实现 集合的位向量表示 集合的单链表表示6.3字典及其抽象数据类型 基本概念 抽象数据类型,6.4字典的顺序表示 存储结构 算法的实现 有序顺序表 与二分法检索6.5字典的散列表示 基本概念 散列函数 碰撞的处理 散列文件,6.1 集合及其抽象数据类型6.1.
2、1 基本概念,集合是数学中最基本的概念,也是一种基本数据结构。在数学中,集合是一些互不相同元素的无序汇集。这些元素称为该集合的成员。集合中的成员可以是一个原子(不可再分解);也可以是一个结构,甚至又是一个集合。集合中的各个元素应该是互不相同的。,列举法:定义一个有穷集,可以将成员放在一对花括号中,成员之间用逗号隔开。例如,2,谓词描述法:集合的大小:集合中所包含的元素的个数。空集 子集 超集 数据结构中讨论的集合,一般有以下限制:1)数据结构讨论的集合总限制为有穷集;2)假定集合中所有元素属同一类型;并且假设元素之间存在一个小于关系“”,也称为有序集。,6.1.2 主要运算,集合也可以定义测试
3、一个元素是否存在于集合中、增加一个元素、删除一个元素等运算,但集合更加关心下面的一些运算。求并集:求交集:求差集:子集:A是B的子集如果集合A是B的子集,反过来也称集合B是A的超集。相等:例如:若,则有,。另外,不等于,同时和相互都不是子集关系。,上面集合间的运算,都可以通过增加元素、删除元素和成员测试等运算来实现。,例如:已知集合A和B,求它们的并集,只要以集合A(或B)为基础,把集合B(或A)的元素逐个插入。如果要求两个集合的交集,只要从A(或B)出发,检查各元素是否在B(或A)中出现,把那些也在另一个集合里出现的元素插入(初态为空集)的集合中即可。求A与B的差集AB时,只要以A为基础,对
4、每个B中的元素做删除运算即可。,6.1.3 抽象数据类型,ADT Set isoperationsSet createEmptySet(void)创建一个空集合。int member(Set,DataType)当时返回真值,否则取假值。int insert(Set,DataType)使作为的一个成员,如果本来就是的成员,则不变。,int delete(Set,DataType)将从中删除,如果本来就不在中,则不改变。int union(Set,Set,Set)求集合和的并集,结果在集合中。int intersection(Set,Set,Set)求集合和的交集,结果在集合中。int diffe
5、rence(Set,Set,Set)求集合和的差集,结果在集合中。int subset(Set,Set)当且仅当是的子集时,函数值才为真。end ADT Set,6.2 集合的实现,位向量表示 单链表表示,6.2.1 位向量表示,位向量是一种每个元素都是二进制位(即0/1值)的数组。当表示的集合存在某个不太大的公共超集时,采用位向量的方式来表示这种集合往往十分有效。,假设需要表示的集合的公共超集中,共有个不同的元素,为叙述的方便,不妨假设这些元素就是整数0,-1等。每个集合可以采用一个有位的位向量来表示。若整数是这个集合的一个元素,则位向量中对应的位为(真),否则为0(假)。,存储结构,由于在
6、C语言中无法直接定义位数组,要定义位向量,需要借助其它方式。一种比较自然的方式,是用长度为n/8的字符数组表示长度为n的字位数组。一个字符用8位二进制编码,它实际上包含了8个二进制位。,位向量表示集合的存储结构:typedef struct int size;/*字符数组的长度*/char*array;/*位向量空间。每一数组元素保存8位。*/BitSet;,下图给出了一个公共超集是从0到9的整数集合,采用位向量表示的存储结构示意图。从图中可以看出每个整数所对应的二进制位的位置。当集合S=1,3,5,7,9时,它的实际存储状态如图(b)所示(注意其中元素的排列方法)。用位向量表示集合时,所占空
7、间的大小与公共超集的大小成正比,而与要表示的集合的大小无关。,算法实现,以位向量表示集合,只有两个集合都是某个公共集合的子集时,它们互相运算才是有效的。由于在位向量定义里并没有关于集合元素的实际信息,只能要求参与运算的两个位向量长度相同。,位运算,假设x和y都是8位的字符,其值分别是:X=01010111Y=11011010。对x和y做各种字位运算,得到的结果如下:x 10101000 x&y 01010010 x y 10001101x|y 11011111x 5 00000110,空集合的创建 与空顺序表的的创建类似,不同之处在于这里省略了每个集合中实际元素个数的变量:BitSet*cre
8、ateEmptySet(int n)将整数index的元素插入集合 将值为index的元素插入集合S的过程,通过将位向量中下标为index的位置为1来完成:int insert(BitSet*s,int index),将整数index的元素从集合中删除 通过将位向量中下标为index的位置为0来完成:int delete(BitSet*s,int index)判断整数index的元素是否属于集合 通过判断位向量中下标为index的位是否为1来完成:int member(BitSet*s,int index),集合与集合的并利用按位的“或”运算实现:int union(BitSet*s0,Bit
9、Set*s1,BitSet*s2)集合与集合的交 这个运算很容易通过位“与”操作实现。int intersection(BitSet*s0,BitSet*s1,BitSet*s2),集合与集合的差 将第一个集合与第二个集合的逆做与运算,就可以达到这个目的。int difference(BitSet*s0,BitSet*s1,BitSet*s2),6.2.2 单链表表示,链接表示方式下,在链表中存放的是集合中元素的实际数值,而不是元素是否属于集合的标记。,存储结构,链表中的每个结点表示集合中的一个元素,具体方式与第二章单链表的结点struct Node类似。不同之处在于:线性表的单链表中,lin
10、k字段表示线性表元素之间的逻辑后继关系,而在这里仅仅是把属于同一集合的所有元素链接成一个整体。因为我们讨论的是有序集,如果将集合中的所有元素按“”关系排序构造有序链表,给集合的某些运算会带来方便。,struct Node;typedef struct Node*PNode;struct Node DataType info;PNode link;typedef struct Node*LinkSet;,集合0,1,2,n-1采用带表头结点的有序链表表示时,如图所示:,求单链表表示集合的交集,int intersectionLink(LinkSet s0,LinkSet s1,LinkSet s
11、2)在有序链表表示的集合中,在s1中找到第一个与s0中相同元素后,其它共同元素不需要从头开始比较,只要从刚才比较成功所结束的位置继续向后检索。因此,只要用两个指针,沿s0和s1从头至尾扫描一遍即可完成。当这两个表的长度为和时,算法的时间总花费最多为()。程序实现,算法实现,集合的赋值 int assignLink(LinkSet s0,LinkSet s1)赋值运算将集合s0拷贝成集合s1,注意这一运算不能简单地将s0的表头结点置成s1的表头结点,因为若这样处理,则对s1的改变将会带来s0的改变。程序实现,插入运算 int insertLink(LinkSet s0,DataType x)插入
12、运算首先要找到适当的插入位置,它有两个参数:一个是被插入元素的信息x;另一个则是被插入的集合s0。程序实现,6.3 字典及其抽象数据类型 基本概念,字典是一种集合,其中每个元素由两部分组成,分别称为关键码和属性(或称为值)。这种包含关键码和属性的二元组称作关联(Association)。抽象地看,一个关联是一个有序对,它可以看成是由关键码值k到属性(值)v的一个对应。字典就是由关键码集合到值集合的二元关系。字典中的元素之间能够根据其关键码进行比较大小,对字典元素的插入、删除和检索等操作一般也以关键码为依据进行。,在实践中使用较多的字典里所有的关键码互不相同,这种关键码具有唯一性的字典,在数学中
13、称为映射(mapping),数据结构里讲的就是这种字典。字典关心的最主要的运算是检索。衡量一个字典检索算法效率的主要标准是检索过程中对关键码的平均比较次数:以及算法的空间开销、算法是否易于理解等因素。,6.3.2 抽象数据类型,假设用Dictionary表示抽象数据类型字典,用DicElement表示字典元素类型,用KeyType 来表示元素中关键码的类型,用Position表示字典中元素的位置。,ADT Dictionary isoperationsDictionary createEmptyDictionary(void)创建一个空字典。int search(Dictionary dic,
14、KeyType key,Position p)在字典dic中检索关键码为key的关联的位置p。int insert(Dictionary dic,DicElement ele)在字典dic中插入关联ele。int delete(Dictionary dic,KeyType key)在字典dic中删除关键码为key的关联。end ADT Dictionary,6.4 字典的顺序表示 6.4.1 存储结构,从逻辑结构出发,字典中的元素是无序的,但为了实现的方便,可以把字典中的元素按关键码的大小组织成一个顺序表。,typedef intKeyType;typedef intDataType;type
15、def struct KeyType key;/*字典元素的关键码字段*/DataType value;/*字典元素的属性字段*/DicElement;typedef struct int MAXNUM;/*字典中元素的个数上界*/int n;/*为字典中实际元素的个数*/DicElement*element.;/*存放字典中的元素*/SeqDictionary;,6.4.2 算法的实现,检索的基本思想是从字典的一端开始顺序扫描,将字典中元素的关键码和给定值比较,如果相等,则检索成功;当扫描结束时,还未找到关键码等于给定值的元素,则检索失败。这称为顺序检索算法。程序实现:int seqSear
16、ch(SeqDictionary*pdic,KeyType key,int*position),在不考虑检索失败的情况下,顺序检索的平均检索长度为:ASL=1P1+2P2+nPn 假设每个元素的检索概率相等,即Pi=1/n,则平均检索长度为 ASL=(1+n)/2。成功检索的平均比较次数约为字典长度的一半。若字典中不存在关键码为key的元素,则需进行n次比较。检索时间为O(n)。,算法代价,顺序检索的优点是算法简单且适应面广。无论字典中元素是否有序均可使用。缺点是平均检索长度较大,特别是当n很大时,检索效率较低。一般情况下,字典中各元素的检索概率不相等。则当P1P2Pn时,平均检索长度最小。因
17、此,如果已知各元素的检索概率,则应将字典中元素按检索概率由大到小排序,以便提高检索效率。,讨论,6.4.3 有序顺序表与二分法检索,一种提高检索效率的方法是将字典元素按关键码递增(或者递减)的顺序排序,这种按照关键码大小排序的顺序表称为有序顺序表。对于有序顺序表,可以还采用顺序检索的方法进行查找,当检索到元素的关键码大于(或者小于)给定值时,就可以返回检索失败的信息。下面介绍的另外一种检索方法,称为二分法检索,是专门为有序顺序表设计的。,二分法检索又称折半检索,是一种效率较高的检索方法,使用这种方法检索时,要求字典的元素在顺序表中按关键码排序。基本思想:首先将给定值key与数组中间位置上元素的
18、关键码比较,如果相等,则检索成功;否则,若key小,则在数组前半部分中继续进行二分法检索,否则在数组后半部分中继续进行二分法检索。这样,经过一次比较就缩小一半的查找区间,如此进行下去,直到能够确定检索成功或检索失败为止。int binarySearch(SeqDictionary*pdic,KeyType key,int*position),二分法检索,分析二分法检索每经过一次比较就将检索范围缩小一半,第i次比较可能比较的元素个数如下表比较次数 可能比较的元素个数 1 1=20 2 2=21 3 4=22 j 2j-1若字典元素个数n刚好为20+21+2j-1=2j-1则最大检索长度为j;若2
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 数据结构 语言 集合 字典
链接地址:https://www.31ppt.com/p-6012007.html