POJ-3630-Phone List-Trie树(键树、数字查找树、基数树)

先看下键树的有关基础知识。
键树中的每个结点不是包含一个关键字,而是只包含组成关键字的符号。例如,若关键字是数值,则结点中只包含一个数位;若关键字是单词,则结点中只包含一个字母字符。这种树会给某种类型关键字的表的查找带来方便。
通常用树的多重链表表示键树。下图是一个例子。

《POJ-3630-Phone List-Trie树(键树、数字查找树、基数树)》

在这个例子中,每个关键字均由a-z这26个小写字母组成。为了表示这些关键字,每上结点均有一个大小为26的指针数组。上图中,一共表示了”abc”,”d”,”da”,”dda”这四个字符串。
键树具有以下性质:
1)关键字的符号的种数决定了指针数组branch的大小,如上例的大小为26;
2)branch数组的下标index代表该符号相对’a’对位置;
3)在结点中采用一个bool变量,确定是否已构成了一个关键字;
4)插入、查找的复杂度均为O(len),len为关键字符串的长度。

然后解答POJ3630题。
题意:给出一组电话号码,判断其中一个号码是否另一个号码的前缀。
分析:具体看代码注释。
代码:

#include <stdio.h> #include <string.h> #define MAX_NODE_SIZE 100000 //最大结点容量,题意最多有10000个号,每个号最多有10位 #define MAX_NUM_SIZE 10 //每个号码串最大长度 #define MAX_DIGIT 10 //每个号码串由0~9的数字组成 struct node { bool isEnd; //表示是否到达了一个串的结束处 struct node* branch[MAX_DIGIT]; //branch指针数组,表示该位置的符号 }; struct node nodesPool[MAX_NODE_SIZE]; //由于用new会超时,故在程序一开始便申请了静态数组 struct node *root; //trie树的根 int nodeNum; //使用nodesPool数组时用到 /*每次运行一个测试用例前均应初始化*/ void init() { for(int i = 0; i < MAX_NODE_SIZE; i++) { nodesPool[i].isEnd = false; for(int j = 0; j < MAX_DIGIT; j++) { nodesPool[i].branch[j] = NULL; } } root = &nodesPool[0]; nodeNum = 1; } /*插入一个电话号码。 *在插入过程中,并判断: *1)在trie树中是否已有一个串为新插入串的前缀; *2)该新插入的串是否为trie树中某个串的前缀。 *若满足以上两种情况,返回false,表示不插入;否则正确插入,返回true *O(len) */ bool insert(char *phoneStr) { int len = strlen(phoneStr); struct node *location = root; for(int i = 0; i < len; i++) { int index = phoneStr[i] – ‘0’; //下标 /*判断情况2),在i指向串最后一个字符时进行判断*/ if(i == len – 1 && location->branch[index] != NULL) { return false; } if(location->branch[index] == NULL) { location->branch[index] = &nodesPool[nodeNum]; nodeNum++; } else { /*判断情况1)*/ if(location->branch[index]->isEnd) return false; } /*不断向前*/ location = location->branch[index]; } location->isEnd = true; //到达该结点,结束。注意:对于每个串,若串长度为n,则需n+1个结点表示 return true; } int main() { int nCases; scanf(“%d”, &nCases); while(nCases–) { init(); int n; scanf(“%d”, &n); bool isConsistent = true; while(n–) { char phoneStr[MAX_NUM_SIZE + 2]; scanf(“%s”, phoneStr); /*即使已能判断出不能正确插入,还得继续循环,因为还有数输入要读取*/ if(!insert(phoneStr)) { isConsistent = false; } } if(isConsistent) printf(“YES/n”); else printf(“NO/n”); } return 0; }

    原文作者:Trie树
    原文地址: https://blog.csdn.net/lihao21/article/details/6173318
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞