本发明属于数据结构和信息检索领域,尤其涉及一种通过16位trie树实现空间优化的词典排序方法。
背景技术:
排序是对数据处理的一种操作,其目的是将一组“无序”的记录序列调整为“有序”的记录序列。近年来,随着互联网的快速发展和智能移动设备的大量普及,尤其是大数据时代的到来,由于网络信息量过于庞大,检索结果信息过多,有用信息不全,检索结果缺乏个性化,在信息检索领域,如何更好地检索到与用户检索请求相匹配的信息是一个值得研究的问题。通常,检索系统往往会采用一定的排序算法对与用户检索请求相关的信息进行排序。16位trie树词典排序算法是在16位trie树结构上进行的一种排序算法,其特点是在进行16位trie树构建的同时完成词典排序。
快速排序算法是冒泡排序的改进版,是目前最快的排序方法。快速排序与16位trie树词典排序算法相比,首先时间上略慢,而且不能处理频繁的更新,每一次更新排序都需要重新分配内存空间进行排序,造成了时间上的浪费,第二,16位trie树词典排序算法不需要数据移动,插入即是有序,基本上不存在数据移动的问题,与插入排序算法相比,16位trie树词典排序算法不需要查找大量数据确定插入位置,而是借助trie树的临近有效节点即可读取排序插入的位置,因此,该算法在时间上更胜一筹。
与快速排序算法相比,16位trie树字典排序算法可随时进行动态排序,而且在构建的同时就能够完成字典的排序,让无序的数据组合变成有序的数据组合,大大节约了额外的排序时间。
技术实现要素:
为了解决上述技术问题,本发明提供一种通过16位trie树实现空间优化的词典排序方法,该方法包括以下步骤:创建空的trie树和空的排序链表;关键字依次插入;既生成tire树又完成了字典排序。本字典算法呈树形,并且每个节点使用16位(bit)表示子节点的情况,因此命名为16位字典树算法。生成16位trie树的词典时,每插入一个关键字key就创建一个链节点,同时根据其关键字key对链表进行有序插入。另外,与快速排序算法对比,16位trie树字典排序算法可随时进行动态排序,而且在构建的同时就能够完成字典的排序,让无序的数据组合变成有序的数据组合,大大节约了额外的排序时间。
为此,本发明实施例公开了一种通过16位trie树实现空间优化的词典排序方法。该方法包括以下步骤:创建空的trie树和空的排序链表;关键字key依次插入;既生成tire树又完成了字典排序。
优选地,所述的16位trie树的词典数据中以类bitnode作为节点类,以类linklist作为链节点类,以类bitindex作为管理类。
优选地,所述类bitindex中用root来表示根节点,仅有一个根节点。
优选地,所述16位trie树中的节点用leafs数组表示当前存储的子节点指针以及链节点指针,其中子节点指针指向当前节点所对应的子节点,链节点指针指向当前节点所对应的链节点,当子节点不存在并且链节点指针也不存在时,leafs元素个数为0,当子节点存在时,leafs元素个数为子节点数量+1(其中链节点指针占用一个元素)。
优选地,所述节点是否为有效节点用hasdata表示,0表示为非有效节点,1表示为有效节点。
优选地,所述索引包括以下步骤:
a.创建空的trie树和空的排序链表;
b.获取到关键字key的第一个字节的值,并获得该字节的高4位值high_4bits,通过当前节点查询表示高4位节点值的子节点是否存在,若对应的子节点存在,获得该高4位节点,并继续以同样方法查询该字节低4位节点,否则插入新节点pbitnode,直到关键字key所有字节插入为止;
c.在进行新节点pbitnode插入时,同时用变量parentnode标记满足以下两个条件的节点记做父节点:该节点是支链上的有效节点(hasdata=1),或者在该支链上有两个以上子节点(包含两个)的父节点;
d.当关键字key完成最后一个节点插入时,该节点记作pnewnode,通过标记的父节点parentnode和当前节点pnewnode获得距离当前节点最近的有效节点,若该最近有效节点存在,则取得该有效节点leafs数组上的链节点指针,记作plistnode链节点,新建一个链节点,在plistnode链节点之前或之后插入新建的链节点,同时在当前节点pnewnode的leafs数组上存储新建的链节点指针(方便定位有效节点的链节点位置);
e.若该最近有效节点不存在,则新建一个链节点,在排序链表头节点phead之后插入新建的链节点,同时在当前节点pnewnode的leafs数组上存储新建的链节点指针;
优选地,所述排序为:生成的链为其所有关键字key从小到大对应的排序结果。
本发明提供一种通过16位trie树实现空间优化的词典排序方法,该方法包括以下步骤:创建空的trie树和空的排序链表;关键字依次插入;既生成tire树又完成了字典排序。本字典算法呈树形,并且每个节点使用16位(bit)表示子节点的情况,因此命名为16位字典树算法。生成16位trie树的词典时,每插入一个关键字key就创建一个链节点,同时根据其关键字key对链表进行有序插入。另外,与快速排序算法对比,16位trie树字典排序算法可随时进行动态排序,而且在构建的同时就能够完成字典的排序,让无序的数据组合变成有序的数据组合,大大节约了额外的排序时间。
应当理解,以上总体说明和以下详细说明都是说明性和实例性的,旨在提供对所要求的本发明的进一步说明。
附图说明
图1是本发明实施例根据关键字key的当前状态实现排序的模块图。
图2是本发明实施例中词典数据trie树的构造图。
图3是本发明实施例中词典数据trie树的排序链表图。
图4是本发明实施例通过16位trie树实现空间优化的词典排序方法的流程图。
具体实施方式
为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步的详细说明。应当理解,此处所述描述的具体实施例仅仅用于解释本发明,并不用于限定本发明。
本发明实施例提供的通过16位trie树实现空间优化的词典排序方法。
如图1所示,是本发明实施例通过16位trie树实现空间优化的词典排序方法的模块图。
步骤s110:创建空的trie树(根节点root),创建空的排序链表(phead-prear)。
插入关键字key,例如:要插入如下的关键字:de,fg,ab,yf,a,dec,dea,ta,fc,fy。
步骤s120:关键字依次插入。
如图2所示,为16位trie树的最终构建结果。根据上例中的关键字数据,这些词之间存在着一些共同的前缀(即相同的父节点),按照这些前缀可以组成一个字典树,树的结点做如下说明:
虚线圆代表非有效节点(即该节点hasdata=0);
实线圆代表树的有效节点(即该节点hasdata=1);
从树的根部root节点到当前有效节点构成的词是词典中的一条完整词条;
节点中用hasdata表示当前节点是否为有效节点,0表示为非有效节点,1表示是有效节点。
步骤s121:以上16位trie树的构建包括以下步骤。
步骤s122:以根节点root构建关键字为“de,fg,ab,yf,a,dec,dea,ta,fc,fy”的16位trie树链表。
步骤s123:获取第一个关键字“de”的第一个字节‘d’,并取得‘d’的高4位值6,通过根节点查询表示节点值为6的子节点是否存在,若存在,则获得‘d’的高4位节点;若不存在,则插入‘d’的高4位节点,若根节点是有效节点或者有两个以上子节点(包含两个)的父节点,则用变量parentnode进行标记,再将‘d’的高4位节点作为根节点,同理查询‘d’的低4位节点,直到关键字“de”所有字节插入为止。
步骤123伪代码如下:
while(ukeylen--)
{
ppnode=pnewnode;//高四位
pnewnode=pnewnode->addchildnode((*pchkey)>>4);
//标记父节点
if(ppnode->leafscount()>1||ppnode->mbhasdata)
{//标记父节点下的有效节点值
pparentnode=ppnode;
pvaildnodevalue=((*pchkey)>>4);
}
ppnode=pnewnode;//低四位
pnewnode=pnewnode->addchildnode((*pchkey)&0x0f);
//标记父节点
if(ppnode->leafscount()>1||ppnode->mbhasdata)
{
pparentnode=ppnode;
pvaildnodevalue=((*pchkey)&0x0f);
}
pnewnode->mbisendnode=true;
pchkey++;
}。
步骤s125:当关键字“de”完成‘e’的低四位节点插入时,该‘e’的低四位节点记作pnewnode1,根据pnewnode1和父节点判断距离pnewnode1最近的有效节点不存在,则新建一个链节点listnode(de),在头节点phead后面进行插入,同时在pnewnode1节点的leafs数组上存储新建的链节点指针(方便定位链节点位置);
当前的排序链表为:phead-listnode(de)-prear。
步骤s126:继续插入上例中第二个关键字“fg”,当“fg”完成‘g’的低四位节点插入时,该‘g’的低四位节点记作pnewnode2,根据pnewnode2和父节点判断距离pnewnode2最近的有效节点为pnewnode1,判断pnewnode1比pnewnode2节点值小,则取pnewnode1节点的leafs数组上的listnode(de)链节点指针,新建一个链节点listnode(fg),在listnode(de)链节点之后插入新建的链节点,同时在pnewnode2的leafs数组上存储新建的链节点指针;
当前的排序链表为:phead-listnode(de)-listnode(fg)-prear。
步骤125伪代码如下:
if(存在最近有效节点)
{
if(最近有效节点在当前节点之后)
{
读最近有效节点的leafs数组上的链节点指针,
记pmaxlistnode节点;
在pmaxlistnode节点之前进行插入新建的链节点;
在当前节点的leafs数组上保存新建链节点指针;
}
else//最近有效节点在当前节点之前
{
读最近有效节点的leafs数组上的链节点指针,
记pminlistnode节点;
在pminlistnode节点之后进行插入新建的链节点;
在当前节点的leafs数组上保存新建的链节点指针;
}
}
else//最近有效节点不存在
{
头节点之后直接插入新建的链节点;
当前节点的leafs数组上保存新建的链节点指针;
}。
继续插入上例中的第三个关键字“ab”,重复上述步骤直到上例中全部关键字插入为止;
最终的的链表排序结果为:phead-listnode(a)-listnode(ab)-listnode(de)-listnode(dea)-listnode(dec)-listnode(fc)-listnode(fg)-listnode(fy)-listnode(ta)-listnode(yf)-prear。
步骤s130:既生成tire树又完成了词典排序;
生成的排序链表如图3所示,是所有关键字key从小到大对应的排序结果。
根据上述对本发明的实施例的具体描述,可以清楚地理解根据本发明提供一种通过16位trie树实现空间优化的词典排序方法,该方法包括以下步骤:创建空的trie树和空的排序链表;关键字依次插入;既生成tire树又完成了字典排序。本字典算法呈树形,并且每个节点使用16位(bit)表示子节点的情况,因此命名为16位字典树算法。生成16位trie树的词典时,每插入一个关键字key就创建一个链节点,同时根据其关键字key对链表进行有序插入,另外,与快速排序算法对比,16位trie树字典排序算法可随时进行动态排序,而且在构建的同时就能够完成字典的排序,让无序的数据组合变成有序的数据组合,大大节约了额外的排序时间。