键树查找基本内容介绍

本文介绍了键树这一数据结构,特别是它的两种存储形式——双链树和Trie树。双链树中,每个节点包含当前字符、指向子树和兄弟节点的指针,用于有序查找。Trie树则利用节点的多个指针域,通过字符直接定位,优化查找效率。在查找过程中,双链树按照字符顺序逐层遍历,Trie树则沿相应指针直接到达目标节点。这两种数据结构在字符串查找中有着广泛应用。
摘要由CSDN通过智能技术生成

问题简介:

        键树,又称数字查找树。它是一棵度>=2的树,树中的每个结点只含有组成关键字的某个符号。例如,如果关键字是数值,则一个结点中只包含一个数位;若关键字是单词,则一个结点只包含一个字母。每个完整的关键字都是从根节点到叶子结点所经过的所有结点的组合。这种特殊的树会给某些类型的关键字的表的查找带来方便。

示意图:

        例如,一组单词集合为{CAR,CAT,CAKE,LIKE,LIE,WHEN,WE},则根据键树的定义,先将首字母相同的单词进行组合:{{CAR,CAT,CAKE} , {LIE,LIKE} , {WE,WHEN}}

        若所得子集的关键字多余一个,则还需按照后一个字母继续分割,知道每个小子集只包含一个关键字。最后所得结果如图所示:

 

        为了操作方便,我们规定键树在同一层中符号从左到右有序,并且结束符$小于任何字符。

键树的储存结构

        键树有两种储存结构,分别是以树的孩子兄弟链表来表示的双链树,和以多重链表来表示的Trie树。

双链树

        此时每个分支节点有三个域:symbol域,用于存储当前的字符;first域,用于指向第一棵子树的根的指针;next域,用于指向右兄弟的指针。同时,叶子结点还有一个单独的infoptr域,用于储存指向该关键字记录的指针。

 储存结构代码:

#define MAXKEYLEN 16  //关键字的最大长度
typedef struct{
    char ch[MAXKEYLEN];  //关键字
    int num;    //关键字的长度

}KeysType;    //关键字的类型

typedef enum {LEAF, BRANCH}  Nodekind;  //结点种类,分为叶子和分支
typedef struct DLTNode{
    char symbol;
    struct DLTNode  *next;    //指向兄弟结点
    NodeKind  kind;
    union{
        Record  *infoptr;    //叶子结点的记录指针
        struct DLTNode  *first;    //指向孩子结点
  }

}DLTNode, *DLTree;

        进行查找时,按照如下规则执行:假设需要查找的关键字为K.ch(0...n-1),其中K.ch[0]到K.ch[n-2]代表关键字所含的n-1个字符,而K.ch[n-1]为结束符$。从双链树的根节点出发,顺着first域查找当前结点的第一颗子树的根节点,比较K.ch[i]与当前symbol域的值是否相同,如果相同,则继续将指针移到下一个first域,否则,则通过next域查找兄弟结点。若直至兄弟结点查找完都为不等,则查找失败。

查找算法代码:

Record *SearchDLtree(DLTree T,KeyType K){    

    DLTree p=T->first;    //指针指向第一个结点
    int i=0;
    while(p && i<K.num){
        while(p&&p->symbol!=K.ch[i]) p=p->next;    //查找关键字的第i位
        if(p && i<K.num-1)  p=p->first;    当前位查找到,准备查找下一位
        i++;
    }
    if(!p) return NULL;    //查找成功
    else return p->infoptr;        //查找失败
}

Trie树

        Trie树又称字典树,树里的每个节点都含有d个指针域。

        其中,d表示最大度,它域关键字的类型有关。如果关键字由字母组成,则d为26个字母加上一个$结束符等于27,同样道理得,数字的d为11。

        若从Trie树的某个节点到叶子结点的路径上每个结点都只有一个孩子,则将该路径上的所有结点压缩成一个叶子节点,且在该叶子节点中存储关键字及指针等信息。

       储存结构代码:

        

typedef struct TrieNode{
    NodeKind kind;
    union{
        struct{KeysType K;Recond *infoptr;} lf;    //叶子结点
        struct{TrieNode *ptr[27];int num;} bh;    //分支结点
  };
}TrieNode,*TrieTree;

        查找时,从根节点出发,沿着对应的指针逐层向下,直到叶子结点,若叶子节点的关键字与给定值线条灯,则成功查找。若叶子节点中的关键字和给定值不相等或分支节点中和给定值相应的指针为空,则不成功。

        查找算法代码:

Record *SearchTrie(TrieTree T,KeysType K){    
for(p=T,i=0;
    p && p->kind==BRANCH && i<K.num;    //p为分支节点
    p=p->bh.ptr[ord(K.ch[i])],++i);    //ord求字符在字母表中的序号
  if(p && p->kind==LEAF&&p->lf.K==K)     //查找成功
  return p->lf.infoptr;        //查找失败
  else return NULL;

}

 

以上就是关于键树查找的简单介绍

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值