看数据结构写代码(60 ) 键树的多重链表表示(Trie树)
来源:互联网 发布:上海矩阵化工有限公司 编辑:程序博客网 时间:2024/05/16 01:00
trie树,是用 树的 多重链表来表示 树的。每个节点 有 d 个指针域。若从键树中的某个节点到叶子节点的路径上每个节点都只有一个孩子,则可以把 路径上的所有节点压缩成一个叶子节点,且在叶子节点中 存储 关键字 以及 根关键字相关的信息。
当节点的度 比较大时,选择 Trie树,要比 双链表树更为合适。
tire树的 数据 压缩 是 挺与众不同的。
下面 给出 具体的 代码:
源代码工程文件网盘地址:http://pan.baidu.com/s/1cyTg6
// TrieTree.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <cstdlib>#include <cstring>#include "stack.h"#define BRANCH_MAX_SIZE 27//分支节点最大指针数#define MAX_SIZE 16#define LEAF_END_CHAR '$'enum E_Kind{E_Kind_Branch,E_Kind_Leaf,};struct KeyType{char k [MAX_SIZE];int len;};void initKey(KeyType * kt,char *k){kt->len = strlen(k);strncpy(kt->k,k,kt->len+1);}typedef struct TrieNode{E_Kind kind;union {struct {TrieNode * ptr[BRANCH_MAX_SIZE];int num;}branch;struct {char record[MAX_SIZE];}leaf;};}* TrieTree;TrieNode * makeNode(E_Kind kind){TrieNode * node = (TrieNode*) malloc(sizeof(TrieNode));node->kind = kind;if (kind == E_Kind_Branch){for (int i = 0; i < BRANCH_MAX_SIZE; i++){node->branch.ptr[i] = NULL;}node->branch.num = 0;}return node;}TrieNode * makeLeafNode(char * key){TrieNode * leaf = makeNode(E_Kind_Leaf);strncpy(leaf->leaf.record,key,strlen(key)+1);return leaf;}void initTree(TrieTree* t){*t = NULL;}void destoryTree(TrieTree * t){if (*t != NULL){TrieTree p = *t;if (p->kind == E_Kind_Branch){for (int i = 0; i < BRANCH_MAX_SIZE; i++){if (p->branch.ptr[i] != NULL){destoryTree(&p->branch.ptr[i]);}}}free(*t);*t = NULL;}}int getIndex(char * k,int i){KeyType kt;initKey(&kt,k);int index = 0;if(i != kt.len){index = kt.k[i] - 'a' + 1;}return index;}struct Result{bool isFind;TrieNode * t;int index;};//找到了返回 保存记录的 叶子节点;//否则返回插入位置Result search(TrieTree t,char * k){KeyType kt;initKey(&kt,k);Result r;for (int i = 0; t && t->kind == E_Kind_Branch && i<= kt.len; i++){int index = getIndex(k,i);r.t = t;r.index = i;t = t->branch.ptr[index];}if (t && t->kind == E_Kind_Leaf && strcmp(t->leaf.record,k) == 0){//节点可以压缩,所以没有 == kt.len的条件.r.isFind = true;r.t = t;}else{r.isFind = false;}return r;}void insertTree(TrieTree *t,char * key){if (*t == NULL){*t = makeNode(E_Kind_Branch);}Result r = search(*t,key);if (r.isFind == false){int index = getIndex(key,r.index);TrieTree p = r.t->branch.ptr[index];TrieNode * leaf = makeLeafNode(key);if (p == NULL){r.t->branch.ptr[index] = leaf;r.t->branch.num ++;}else{TrieTree q = r.t;int times = r.index+1;int len = strlen(key);while (times <= len){//为字符 相同的节点 建立 分支int index1 = getIndex(key,times);int index2= getIndex(p->leaf.record,times);TrieNode * branch = makeNode(E_Kind_Branch);q->branch.ptr[index] = branch;if (index1 != index2){branch->branch.ptr[index1] = leaf;branch->branch.ptr[index2] = p;branch->branch.num += 2;break;}else{branch->branch.num = 1;q = branch;index = index1;times++;}}}}}void deleteTrie(TrieTree * t,char * k){if(*t != NULL){linkStack stack;stackInit(&stack);stackPush(&stack,*t);KeyType kt;initKey(&kt,k);TrieTree p = *t;int i = 0;for (; p && p->kind == E_Kind_Branch && i <= kt.len; i++){int index = getIndex(k,i);stackPush(&stack,p);p = p->branch.ptr[index];}if (p && p->kind == E_Kind_Leaf && strcmp(p->leaf.record,k) == 0){TrieTree brotherNode = NULL;while (!stackEmpty(stack)){TrieTree f;stackPop(&stack,&f);free(p);int index = getIndex(k,i);f->branch.ptr[i] = NULL;f->branch.num --;if (f->branch.num == 0){p = f;i--;if (f == *t){//空树了..free(*t);*t = NULL;}}else{break;}}}else{//没找到return;}}}static char testArray[][MAX_SIZE] = {//18 个 "cao","cai","chang","chao","cha","chen",//6 "wen","wang","wu",//3 "zhao",//1 "li","lan","long","liu",//4 "yun","yang",//2 "zha","l", }; int _tmain(int argc, _TCHAR* argv[]){TrieTree root;initTree(&root);for (int i = 0; i < 18; i++){insertTree(&root,testArray[i]);}for (int i = 0; i < 18; i++){char * s = testArray[i];Result r = search(root,s);if (r.isFind){printf("查找%s ,结果为:%s\n",s,r.t->leaf.record);}else{printf("查找%s ,未找到\n",s);}}destoryTree(&root);return 0;}运行截图:
0 0
- 看数据结构写代码(60 ) 键树的多重链表表示(Trie树)
- 看数据结构写代码(38) 图的邻接多重表表示法与实现
- 看数据结构写代码(36) 图的邻接表表示与实现
- 看数据结构写代码(57) AVL树的删除
- 看数据结构写代码(59) 键树的双链表示法
- 看数据结构写代码(31)树的二叉链表的实现
- 看数据结构写代码(9)链栈的实现
- 看数据结构写代码(42)最小生成树
- 看数据结构写代码(54)次优查找树
- 看数据结构写代码(58) B-树
- 看数据结构写代码(66) 败者树
- 看数据结构写代码(30) 树的双亲孩子表示法的实现
- 40. 数据结构笔记之四十图的邻接多重链表表示实现
- 看数据结构写代码(29) 树的双亲表示法
- 看数据结构写代码(3)顺序表的 实现
- 看数据结构写代码(8)顺序栈的实现
- 看数据结构写代码(19) 数组的实现
- 看数据结构写代码(4)单链表
- C++ 虚函数表解析
- 上海百达翡丽手表维修
- 常量数据的处理思路
- 【Java二十周年】我会勇敢的走下去
- 表单控件(下拉选择框select)
- 看数据结构写代码(60 ) 键树的多重链表表示(Trie树)
- 多项式相加
- 正则表达式
- Win8 Metro(C#)数字图像处理--4图像颜色空间描述
- [LeetCode] Isomorphic Strings
- 顺序栈的一些操作
- Unique Binary Search Trees
- 利用Java NIO 实现文件监控功能。
- 表单控件(文本域textarea)