问题描述
- 多级索引算法只增删查改
-
多级索引算法
在链表描述的具有length个元素的集合中进行搜索,至多需要length次访问节点。如果在链的中部节点加一个指针,并记录头部到中部的距离,则访问的节点数可以减少到n/2+1次。搜索时,首先将欲搜索的索引与头部到中部的距离进行比较,如果欲搜索的索引较小,则仅需搜索链表的左半部,否则,只要从中部开始搜索右半部。
图3-1a的链表中有七个元素。该链表有一个头节点和一个尾节点。节点中的数表示该节点的索引值。如果要访问索引值为7的节点,对该链表的搜索要进行七次。在图3-1b中,增加了一个头部到中部的指针,指针上的数字表示头部到中部的距离。采用图3-1b中的办法,可以把最坏情况下的比较次数减为四次。搜索一个索引时,首先将它与头部到中间的距离进行比较,然后根据得到的结果,或者在链的左半部搜索或者在链的右半部搜索。
如果在链表的左半部分和右半部分的中间节点再增加一个指针,可以进一步减少最坏情况下的搜索比较次数。如图3-1c,在该图中有三条链。0级链就是图3-1a中的初始链,包括了所有的七个元素。1级链包括了第2、4、6个元素,而2级链只包括了第4个元素。寻找某一个索引指定的元素时,只需要在2级链上比较一次,根据比较结果,在1级链上比较一次,最后在0级链上找出所需的元素。采用图3-1c中的3级链表结构,允许在链表中进行折半查找,对所有的索引至多需要3次比较。
对一个有n个元素的多级链接结构来说,0级链包括全部的n个节点,1级链包括n/2个节点,2级链包括n/4个节点,而每2i个元素有一个i级链指针。当且仅当一个节点在0~i级链上,但不在i+1级链上时,我们就称该节点是i级链节点。在图3-1c中,索引为4的节点是2级链上的唯一节点,而索引为6的节点是1级链节点。
图3-1c所示的结构称为多级链表结构。在该结构中,有一组有层次的链,通过这中有层次的链,实现折半查找。
在进行插入和删除操作时,要完整保持图3-1c的结构,必须耗时O(n)。如果可以采取适当放宽结构,只要使得在删除和插入后尽量逼近图3-1c的结构就可以降低保持结构的开销。在这种结构只能管,有n/2i个节点为i级链节点,所以我们可以认为在进行插入时,新节点属于i级链的概率为1/2i。在确定新节点的级时,应考虑各种可能的情况。因此,把新节点作为i级链的可能性定为pi。图3-1c中,p=0.5。
假设要在索引6的位置插入一个新的节点,首先要在链中找到索引为5和6的节点,然后在0级链上插入这个新的节点。接下来,要为新节点分配一个级,分配过程由随机数来确定。
若新节点为i级链元素,那么,把这个节点分别插入到1~i级链中。最后,调整每一级链上新的节点左边节点到下一节点的距离。
删除操作和插入操作类似,当删除一个节点时,必须要把这个节点从它的所有级别链上删除,同时调整该节点左边的节点到下一个节点的距离。
关于级的分配,前面已经说到,新节点作为i级链的可能性为pi。换种思路,可以认为i-1级链中的节点属于i级链的概率为p。假设有一随机数产生器所产生的数在0到RAND_MAX之间。则下一次所产生的随机数小于等于CutOff=p*RAND_MAX的概率为p。因此,若下一随机术小于等于CutOff,则新节点应在1级链上。接下来确定新节点是否在2级链上。重复这个过程,直到一随机数大于CutOff为止。
以下是确定节点的级的分配的代码
int level=0;
while (rand()<=CutOff) level++;
这种方法潜在的缺点是可能为某些节点分配特别大的级。为避免这种情况,可以设定新节点的级不大于链上已有节点的最大级加1。根据以上算法写出此算法的检索、插入和删除指定位置元素的操作的函数。(只写出一个思路也可以)
时间: 2024-09-27 23:27:18