字典树简介、应用以及与哈希表的比较
来源:互联网 发布:http使用的端口号 编辑:程序博客网 时间:2024/06/08 09:28
题目要求:
1、设计并实现N-array trie,包括初始化,查找,插入,删除等。2、应用trie结构实现文本文档的索引化,首先扫描文本文档,然后利用trie结构记录单词行号,最后在trie上实现查询3、用户的查询可以是针对一个单词,也可以是某些字母开头的。
我的思路:
根据题目的要求,用字典树这一数据结构实现最为符合,下面介绍一下字典树:
字典树介绍:
我们拿存储英文单词的字典树为例,从实质上来讲,该字典树就是一个26叉树。(若是储存数字如电话号码,那么就是一个10叉树)。比如说我想储存he,her,boy这三个单词,那么其结构如下图所示:
总结其基本性质如下:根节点不包含字符,除根节点意外每个节点至多包含一个单词。从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。
代码实现:
TrieNode类(节点类):string rownum(储存行号),26个指向TrieNode的指针(*a,*b,……),构造函数等;Trie类(树):root(根节点)storeWord()(插入单词的方法):从根节点向子节点遍历(若子节点为空,则新建子节点,直到到达对应位置)queryWord(查询单词行号):从根节点向子节点遍历到达对应位置返回行号
其中题目中提到的查询以某些字母开头的单词,那么只需遍历以该节点为根的子树即可(比如层次遍历)。如下,想查询以he开头的单词,遍历蓝色圈起来的子树。
对字典树的分析:
优点:
1、插入,查询,删除等操作复杂度为O(h),其中h为单词的长度。为什么会这么快呢,本质是空间换时间(空间复杂度为26的h次方),利用指针来避免做其他不必要的查找。(初始化的时间复杂度为n O(h),n为单词个数)2、当储存大量单词或者说储存的单词有着共同前缀时节省了空间。(比如说用线性存储boy,boyfriend如用trie存储的差别)
缺点:
指针占用的空间,空间复杂度大。如果储存少量的单词,并不能节省空间。
字典树的应用:
1、 字符串检索:事先将已知的一些字符串(字典)的有关信息保存到trie树里,查找另外一些未知字符串是否出现过或者出现频率。(本题既是如此)2、 字符串最长公共前缀(转化为寻找共同祖先问题)
与哈希的比较
实际效果:
我存储26400行的单词,其中查询很快,达到了预期,但初始化过程表现很差,用时约3分钟。
我的改进:
在每个节点直接申请所有的指针,来获得连续的空间,防止内存过于碎片化,但效果并不好。
下面是代码版本一
#include <stdio.h>#include<iostream>#include<string.h>using namespace std;#include <stdio.h>#include<string.h>#include <iostream> #include <cstdlib>#include <cstdio>#include <stack> #include <string>#include <fstream> #include <sstream>#include <iostream>#include <vector>using namespace std; class BinaryTreeNode//二叉树的节点类{public: BinaryTreeNode() { a = b= c = d = e= f =g=h=i=j=k=l=m=n=o=p=q=r=s=t=u=v=w=x=y=z=0; } BinaryTreeNode(string num) { rownum = num; a = b= c = d = e= f =g=h=i=j=k=l=m=n=o=p=q=r=s=t=u=v=w=x=y=z=0; } //BinaryTreeNode(char c, BinaryTreeNode* left, BinaryTreeNode* right) { data = c; leftChild = left; rightChild = right; } string rownum ; BinaryTreeNode* a;BinaryTreeNode* b;BinaryTreeNode* c;BinaryTreeNode* d;BinaryTreeNode* e;BinaryTreeNode* f; BinaryTreeNode* g;BinaryTreeNode* h;BinaryTreeNode* i;BinaryTreeNode* j;BinaryTreeNode* k;BinaryTreeNode* l; BinaryTreeNode* m;BinaryTreeNode* n;BinaryTreeNode* o;BinaryTreeNode* p;BinaryTreeNode* q;BinaryTreeNode* r; BinaryTreeNode* s;BinaryTreeNode* t;BinaryTreeNode* u;BinaryTreeNode* v;BinaryTreeNode* w;BinaryTreeNode* x; BinaryTreeNode* y;BinaryTreeNode* z;};class Node //队列类中用链表存{public: BinaryTreeNode *data; Node *next; Node() { next = NULL; } Node(BinaryTreeNode *item, Node* link = NULL) { data = item; next = link; }};//队列类,作为层次遍历的辅助数据结构用class LinkQueue{private: Node *front, *rear;public: LinkQueue() { rear = front = new Node; }; bool empty() { return front == rear; } void outQueue(BinaryTreeNode * &e)//出队列 { Node *tmpPtr = front->next; e = tmpPtr->data; front->next = tmpPtr->next; if (rear == tmpPtr) rear = front; delete tmpPtr; } void inQueue(BinaryTreeNode * &e)//入队列 { Node *tmpPtr = new Node(e); rear->next = tmpPtr; rear = tmpPtr; }};//二叉树类class BinaryTree{public: BinaryTree() { root = 0; } void insertaChild(BinaryTreeNode* t, string rownum)//插入A孩子 { t->a = new BinaryTreeNode(rownum); } void insertbChild(BinaryTreeNode* t, string rownum)//插入B孩子 { t->b = new BinaryTreeNode(rownum); } void insertcChild(BinaryTreeNode* t, string rownum)//插入C孩子 { t->c = new BinaryTreeNode(rownum); } void insertdChild(BinaryTreeNode* t, string rownum)//插入D孩子 { t->d = new BinaryTreeNode(rownum); } void inserteChild(BinaryTreeNode* t, string rownum)//插入E孩子 { t->e = new BinaryTreeNode(rownum); } void insertfChild(BinaryTreeNode* t, string rownum)//插入F孩子 { t->f = new BinaryTreeNode(rownum); } void insertgChild(BinaryTreeNode* t, string rownum)//插入G孩子 { t->g = new BinaryTreeNode(rownum); } void inserthChild(BinaryTreeNode* t, string rownum)//插入H孩子 { t->h = new BinaryTreeNode(rownum); } void insertiChild(BinaryTreeNode* t, string rownum)//插入I孩子 { t->i = new BinaryTreeNode(rownum); } void insertjChild(BinaryTreeNode* t, string rownum)//插入J孩子 { t->j = new BinaryTreeNode(rownum); } void insertkChild(BinaryTreeNode* t, string rownum)//插入K孩子 { t->k = new BinaryTreeNode(rownum); } void insertlChild(BinaryTreeNode* t, string rownum)//插入L孩子 { t->l = new BinaryTreeNode(rownum); } void insertmChild(BinaryTreeNode* t, string rownum)//插入M孩子 { t->m = new BinaryTreeNode(rownum); } void insertnChild(BinaryTreeNode* t, string rownum)//插入N孩子 { t->n = new BinaryTreeNode(rownum); } void insertoChild(BinaryTreeNode* t, string rownum)//插入O孩子 { t->o = new BinaryTreeNode(rownum); } void insertpChild(BinaryTreeNode* t, string rownum)//插入P孩子 { t->p = new BinaryTreeNode(rownum); } void insertqChild(BinaryTreeNode* t, string rownum)//插入Q孩子 { t->q = new BinaryTreeNode(rownum); } void insertrChild(BinaryTreeNode* t, string rownum)//插入R孩子 { t->r = new BinaryTreeNode(rownum); } void insertsChild(BinaryTreeNode* t, string rownum)//插入S孩子 { t->s = new BinaryTreeNode(rownum); } void inserttChild(BinaryTreeNode* t, string rownum)//插入T孩子 { t->t = new BinaryTreeNode(rownum); } void insertuChild(BinaryTreeNode* t, string rownum)//插入U孩子 { t->u = new BinaryTreeNode(rownum); } void insertvChild(BinaryTreeNode* t, string rownum)//插入V孩子 { t->v = new BinaryTreeNode(rownum); } void insertwChild(BinaryTreeNode* t, string rownum)//插入W孩子 { t->w = new BinaryTreeNode(rownum); } void insertxChild(BinaryTreeNode* t, string rownum)//插入X孩子 { t->x = new BinaryTreeNode(rownum); } void insertyChild(BinaryTreeNode* t, string rownum)//插入Y孩子 { t->y = new BinaryTreeNode(rownum); } void insertzChild(BinaryTreeNode* t, string rownum)//插入Z孩子 { t->z = new BinaryTreeNode(rownum); } //下面是接收一个单词储存到树中的方法 void storeWord(string word ,string rownum) { int length=word.length();//获取当前单词的长度 BinaryTreeNode* current = this->root;//current用来遍历树 //下面将word的字母一个个取出来判断该单词在树中的位置 for(int i=0;i<length;i++) { string first; first=word.substr(i,1);//依次获取字母 cout << "当前的字母是:"+first<< endl; if(i<length-1)//还没到最终的位置 { if(first.compare("a")==0) { if(current->a==NULL)//若当前节点没有儿子则插入新儿子 { this->insertaChild(current,"0"); current=current->a; } else//当前节点有该儿子 { current=current->a; } } else if(first.compare("b")==0) { if(current->b==NULL)//若当前节点没有儿子则插入新儿子 { this->insertbChild(current,"0"); current=current->b; } else//当前节点有该儿子 { current=current->b; } } else if(first.compare("c")==0) { if(current->c==NULL)//若当前节点没有儿子则插入新儿子 { this->insertcChild(current,"0"); current=current->c; } else//当前节点有该儿子 { current=current->c; } } else if(first.compare("d")==0) { if(current->d==NULL)//若当前节点没有儿子则插入新儿子 { this->insertdChild(current,"0"); current=current->d; } else//当前节点有该儿子 { current=current->d; } } else if(first.compare("e")==0) { if(current->e==NULL)//若当前节点没有儿子则插入新儿子 { this->inserteChild(current,"0"); current=current->e; } else//当前节点有该儿子 { current=current->e; } } else if(first.compare("f")==0) { if(current->f==NULL)//若当前节点没有儿子则插入新儿子 { this->insertfChild(current,"0"); current=current->f; } else//当前节点有该儿子 { current=current->f; } } else if(first.compare("g")==0) { if(current->g==NULL)//若当前节点没有儿子则插入新儿子 { this->insertgChild(current,"0"); current=current->g; } else//当前节点有该儿子 { current=current->g; } } else if(first.compare("h")==0) { if(current->h==NULL)//若当前节点没有儿子则插入新儿子 { this->inserthChild(current,"0"); current=current->h; } else//当前节点有该儿子 { current=current->h; } } else if(first.compare("i")==0) { if(current->i==NULL)//若当前节点没有儿子则插入新儿子 { this->insertiChild(current,"0"); current=current->i; } else//当前节点有该儿子 { current=current->i; } } else if(first.compare("j")==0) { if(current->j==NULL)//若当前节点没有儿子则插入新儿子 { this->insertjChild(current,"0"); current=current->j; } else//当前节点有该儿子 { current=current->j; } } else if(first.compare("k")==0) { if(current->k==NULL)//若当前节点没有儿子则插入新儿子 { this->insertkChild(current,"0"); current=current->k; } else//当前节点有该儿子 { current=current->k; } } else if(first.compare("l")==0) { if(current->l==NULL)//若当前节点没有儿子则插入新儿子 { this->insertlChild(current,"0"); current=current->l; } else//当前节点有该儿子 { current=current->l; } } else if(first.compare("m")==0) { if(current->m==NULL)//若当前节点没有儿子则插入新儿子 { this->insertmChild(current,"0"); current=current->m; } else//当前节点有该儿子 { current=current->m; } } else if(first.compare("n")==0) { if(current->n==NULL)//若当前节点没有儿子则插入新儿子 { this->insertnChild(current,"0"); current=current->n; } else//当前节点有该儿子 { current=current->n; } } else if(first.compare("o")==0) { if(current->o==NULL)//若当前节点没有儿子则插入新儿子 { this->insertoChild(current,"0"); current=current->o; } else//当前节点有该儿子 { current=current->o; } } else if(first.compare("p")==0) { if(current->p==NULL)//若当前节点没有儿子则插入新儿子 { this->insertpChild(current,"0"); current=current->p; } else//当前节点有该儿子 { current=current->p; } } else if(first.compare("q")==0) { if(current->q==NULL)//若当前节点没有儿子则插入新儿子 { this->insertqChild(current,"0"); current=current->q; } else//当前节点有该儿子 { current=current->q; } } else if(first.compare("r")==0) { if(current->r==NULL)//若当前节点没有儿子则插入新儿子 { this->insertrChild(current,"0"); current=current->r; } else//当前节点有该儿子 { current=current->r; } } else if(first.compare("s")==0) { if(current->s==NULL)//若当前节点没有儿子则插入新儿子 { this->insertsChild(current,"0"); current=current->s; } else//当前节点有该儿子 { current=current->s; } } else if(first.compare("t")==0) { if(current->t==NULL)//若当前节点没有儿子则插入新儿子 { this->inserttChild(current,"0"); current=current->t; } else//当前节点有该儿子 { current=current->t; } } else if(first.compare("u")==0) { if(current->u==NULL)//若当前节点没有儿子则插入新儿子 { this->insertuChild(current,"0"); current=current->u; } else//当前节点有该儿子 { current=current->u; } } else if(first.compare("v")==0) { if(current->v==NULL)//若当前节点没有儿子则插入新儿子 { this->insertvChild(current,"0"); current=current->v; } else//当前节点有该儿子 { current=current->v; } } else if(first.compare("w")==0) { if(current->w==NULL)//若当前节点没有儿子则插入新儿子 { this->insertwChild(current,"0"); current=current->w; } else//当前节点有该儿子 { current=current->w; } } else if(first.compare("x")==0) { if(current->x==NULL)//若当前节点没有儿子则插入新儿子 { this->insertxChild(current,"0"); current=current->x; } else//当前节点有该儿子 { current=current->x; } } else if(first.compare("y")==0) { if(current->y==NULL)//若当前节点没有儿子则插入新儿子 { this->insertyChild(current,"0"); current=current->y; } else//当前节点有该儿子 { current=current->y; } } else if(first.compare("z")==0) { if(current->z==NULL)//若当前节点没有儿子则插入新儿子 { this->insertzChild(current,"0"); current=current->z; } else//当前节点有该儿子 { current=current->z; } } } else//到了最终的位置 { if(first.compare("a")==0) { if(current->a==NULL)//若当前节点没有儿子则插入新儿子 { this->insertaChild(current,word+":"+rownum); current=current->a; } else { this->insertaChild(current,word+":"+rownum); } } else if(first.compare("b")==0) { if(current->b==NULL)//若当前节点没有儿子则插入新儿子 { this->insertbChild(current,word+":"+rownum); current=current->b; } else { this->insertbChild(current,word+":"+rownum); } } else if(first.compare("c")==0) { if(current->c==NULL)//若当前节点没有儿子则插入新儿子 { this->insertcChild(current,word+":"+rownum); current=current->c; } else { this->insertcChild(current,word+":"+rownum); } } else if(first.compare("d")==0) { if(current->d==NULL)//若当前节点没有儿子则插入新儿子 { this->insertdChild(current,word+":"+rownum); current=current->d; } else { this->insertdChild(current,word+":"+rownum); } } else if(first.compare("e")==0) { if(current->e==NULL)//若当前节点没有儿子则插入新儿子 { this->inserteChild(current,word+":"+rownum); current=current->e; } else { this->inserteChild(current,word+":"+rownum); } } else if(first.compare("f")==0) { if(current->f==NULL)//若当前节点没有儿子则插入新儿子 { this->insertfChild(current,word+":"+rownum); current=current->f; } else { this->insertfChild(current,word+":"+rownum); } } else if(first.compare("g")==0) { if(current->g==NULL)//若当前节点没有儿子则插入新儿子 { this->insertgChild(current,word+":"+rownum); current=current->g; } else { this->insertgChild(current,word+":"+rownum); } } else if(first.compare("h")==0) { if(current->h==NULL)//若当前节点没有儿子则插入新儿子 { this->inserthChild(current,word+":"+rownum); current=current->h; } else { this->inserthChild(current,word+":"+rownum); } } else if(first.compare("i")==0) { if(current->i==NULL)//若当前节点没有儿子则插入新儿子 { this->insertiChild(current,word+":"+rownum); current=current->i; } else { this->insertiChild(current,word+":"+rownum); } } else if(first.compare("j")==0) { if(current->j==NULL)//若当前节点没有儿子则插入新儿子 { this->insertjChild(current,word+":"+rownum); current=current->j; } else { this->insertjChild(current,word+":"+rownum); } } else if(first.compare("k")==0) { if(current->k==NULL)//若当前节点没有儿子则插入新儿子 { this->insertkChild(current,word+":"+rownum); current=current->k; } else { this->insertkChild(current,word+":"+rownum); } } else if(first.compare("l")==0) { if(current->l==NULL)//若当前节点没有儿子则插入新儿子 { this->insertlChild(current,word+":"+rownum); current=current->l; } else { this->insertlChild(current,word+":"+rownum); } } else if(first.compare("m")==0) { if(current->m==NULL)//若当前节点没有儿子则插入新儿子 { this->insertmChild(current,word+":"+rownum); current=current->m; } else { this->insertmChild(current,word+":"+rownum); } } else if(first.compare("n")==0) { if(current->n==NULL)//若当前节点没有儿子则插入新儿子 { this->insertnChild(current,word+":"+rownum); current=current->n; } else { this->insertnChild(current,word+":"+rownum); } } else if(first.compare("o")==0) { if(current->o==NULL)//若当前节点没有儿子则插入新儿子 { this->insertoChild(current,word+":"+rownum); current=current->o; } else { this->insertoChild(current,word+":"+rownum); } } else if(first.compare("p")==0) { if(current->p==NULL)//若当前节点没有儿子则插入新儿子 { this->insertpChild(current,word+":"+rownum); current=current->p; } else { this->insertpChild(current,word+":"+rownum); } } else if(first.compare("q")==0) { if(current->q==NULL)//若当前节点没有儿子则插入新儿子 { this->insertqChild(current,word+":"+rownum); current=current->q; } else { this->insertqChild(current,word+":"+rownum); } } else if(first.compare("r")==0) { if(current->r==NULL)//若当前节点没有儿子则插入新儿子 { this->insertrChild(current,word+":"+rownum); current=current->r; } else { this->insertrChild(current,word+":"+rownum); } } else if(first.compare("s")==0) { if(current->s==NULL)//若当前节点没有儿子则插入新儿子 { this->insertsChild(current,word+":"+rownum); current=current->s; } else { this->insertsChild(current,word+":"+rownum); } } else if(first.compare("t")==0) { if(current->t==NULL)//若当前节点没有儿子则插入新儿子 { this->inserttChild(current,word+":"+rownum); current=current->t; } else { this->inserttChild(current,word+":"+rownum); } } else if(first.compare("u")==0) { if(current->u==NULL)//若当前节点没有儿子则插入新儿子 { this->insertuChild(current,word+":"+rownum); current=current->u; } else { this->insertuChild(current,word+":"+rownum); } } else if(first.compare("v")==0) { if(current->v==NULL)//若当前节点没有儿子则插入新儿子 { this->insertvChild(current,word+":"+rownum); current=current->v; } else { this->insertvChild(current,word+":"+rownum); } } else if(first.compare("w")==0) { if(current->w==NULL)//若当前节点没有儿子则插入新儿子 { this->insertwChild(current,word+":"+rownum); current=current->w; } else { this->insertwChild(current,word+":"+rownum); } } else if(first.compare("x")==0) { if(current->x==NULL)//若当前节点没有儿子则插入新儿子 { this->insertxChild(current,word+":"+rownum); current=current->x; } else { this->insertxChild(current,word+":"+rownum); } } else if(first.compare("y")==0) { if(current->y==NULL)//若当前节点没有儿子则插入新儿子 { this->insertyChild(current,word+":"+rownum); current=current->y; } else { this->insertyChild(current,word+":"+rownum); } } else if(first.compare("z")==0) { if(current->z==NULL)//若当前节点没有儿子则插入新儿子 { this->insertzChild(current,word+":"+rownum); current=current->z; } else { this->insertzChild(current,word+":"+rownum); } } } } } // 下面的方法用来查询一个单词返回单词的行号 string queryWord(string word) { int length=word.length();//获取当前单词的长度 BinaryTreeNode* current = this->root;//current用来遍历树 //下面将word的字母一个个取出来判断该单词在树中的位置 for(int i=0;i<length;i++) { string first; first=word.substr(i,1);//依次获取字母 if(i<length-1)//还没到最终的位置 { if(first.compare("a")==0) { if(current->a==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->a; } } else if(first.compare("b")==0) { if(current->b==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->b; } } else if(first.compare("c")==0) { if(current->c==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->c; } } else if(first.compare("d")==0) { if(current->d==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->d; } } else if(first.compare("e")==0) { if(current->e==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->e; } } else if(first.compare("f")==0) { if(current->f==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->f; } } else if(first.compare("g")==0) { if(current->g==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->g; } } else if(first.compare("h")==0) { if(current->h==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->h; } } else if(first.compare("i")==0) { if(current->i==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->i; } } else if(first.compare("j")==0) { if(current->j==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->j; } } else if(first.compare("k")==0) { if(current->k==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->k; } } else if(first.compare("l")==0) { if(current->l==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->l; } } else if(first.compare("m")==0) { if(current->m==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->m; } } else if(first.compare("n")==0) { if(current->n==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->n; } } else if(first.compare("o")==0) { if(current->o==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->o; } } else if(first.compare("p")==0) { if(current->p==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->p; } } else if(first.compare("q")==0) { if(current->q==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->q; } } else if(first.compare("r")==0) { if(current->r==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->r; } } else if(first.compare("s")==0) { if(current->s==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->s; } } else if(first.compare("t")==0) { if(current->t==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->t; } } else if(first.compare("u")==0) { if(current->u==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->u; } } else if(first.compare("v")==0) { if(current->v==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->v; } } else if(first.compare("w")==0) { if(current->w==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->w; } } else if(first.compare("x")==0) { if(current->x==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->x; } } else if(first.compare("y")==0) { if(current->y==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->y; } } else if(first.compare("z")==0) { if(current->z==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//当前节点有该儿子 { current=current->z; } } } else//到了最终的位置 { if(first.compare("a")==0) { if(current->a==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->a); return current->a->rownum; } } else if(first.compare("b")==0) { if(current->b==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->b); return current->b->rownum; } } else if(first.compare("c")==0) { if(current->c==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->c); return current->c->rownum; } } else if(first.compare("d")==0) { if(current->d==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->d); return current->d->rownum; } } else if(first.compare("e")==0) { if(current->e==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->e); return current->e->rownum; } } else if(first.compare("f")==0) { if(current->f==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->f); return current->f->rownum; } } else if(first.compare("g")==0) { if(current->g==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->g); return current->g->rownum; } } else if(first.compare("h")==0) { if(current->h==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->h); return current->h->rownum; } } else if(first.compare("i")==0) { if(current->i==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->i); return current->i->rownum; } } else if(first.compare("j")==0) { if(current->j==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->j); return current->j->rownum; } } else if(first.compare("k")==0) { if(current->k==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->k); return current->k->rownum; } } else if(first.compare("l")==0) { if(current->l==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->l); return current->l->rownum; } } else if(first.compare("m")==0) { if(current->m==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->m); return current->m->rownum; } } else if(first.compare("n")==0) { if(current->n==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->n); return current->n->rownum; } } else if(first.compare("o")==0) { if(current->o==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->o); return current->o->rownum; } } else if(first.compare("p")==0) { if(current->p==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->p); return current->p->rownum; } } else if(first.compare("q")==0) { if(current->q==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->q); return current->q->rownum; } } else if(first.compare("r")==0) { if(current->r==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->r); return current->r->rownum; } } else if(first.compare("s")==0) { if(current->s==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->s); return current->s->rownum; } } else if(first.compare("t")==0) { if(current->t==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->t); return current->t->rownum; } } else if(first.compare("u")==0) { if(current->u==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->u); return current->u->rownum; } } else if(first.compare("v")==0) { if(current->v==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->v); return current->v->rownum; } } else if(first.compare("w")==0) { if(current->w==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->w); return current->w->rownum; } } else if(first.compare("x")==0) { if(current->x==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->x); return current->x->rownum; } } else if(first.compare("y")==0) { if(current->y==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->y); return current->y->rownum; } } else if(first.compare("z")==0) { if(current->z==NULL)//若当前节点没有儿子则表示没有这个单词 { return "-1";//返回-1表示查询失败 } else//查询成功,返回行号 { levelOrder(current->z); return current->z->rownum; } } } } } void levelOrder(BinaryTreeNode* t)//层次遍历 { LinkQueue q; bool isNullAtFirst = true; while (t) { if(t->rownum.compare("0")!=0)//如果不是0表示有单词存储在这个位置 cout << t->rownum<< endl; if (t->a) q.inQueue(t->a); if (t->b) q.inQueue(t->b); if (t->c) q.inQueue(t->c); if (t->d) q.inQueue(t->d); if (t->e) q.inQueue(t->e); if (t->f) q.inQueue(t->f); if (t->g) q.inQueue(t->g); if (t->h) q.inQueue(t->h); if (t->i) q.inQueue(t->i); if (t->j) q.inQueue(t->j); if (t->k) q.inQueue(t->k); if (t->l) q.inQueue(t->l); if (t->m) q.inQueue(t->m); if (t->n) q.inQueue(t->n); if (t->o) q.inQueue(t->o); if (t->p) q.inQueue(t->p); if (t->q) q.inQueue(t->q); if (t->r) q.inQueue(t->r); if (t->s) q.inQueue(t->s); if (t->t) q.inQueue(t->t); if (t->u) q.inQueue(t->u); if (t->v) q.inQueue(t->v); if (t->w) q.inQueue(t->w); if (t->x) q.inQueue(t->x); if (t->y) q.inQueue(t->y); if (t->z) q.inQueue(t->z); if (q.empty()) return; q.outQueue(t); } } // void preOrderForCount(BinaryTreeNode* t)//用了前序遍历的方法来计算二叉树节点数目 // { // if (t) // { // count++; // preOrderForCount(t->leftChild); // preOrderForCount(t->rightChild); // } // } // int height(BinaryTreeNode* t)//返回一个节点的高度 // { // if (!t) return 0; // int heightLeft = height(t->leftChild); // int heightRight = height(t->rightChild); // if (heightLeft > heightRight) return ++heightLeft; // else return ++heightRight; // } // int size()//返回二叉树节点数目 // { // count = 0; // preOrderForCount(root); // return count; // } BinaryTreeNode* root; int count ;};int main(){ BinaryTree b; b.root = new BinaryTreeNode(); // b.storeWord("boy","3"); // b.storeWord("boyfriend","4"); // b.levelOrder(b.root); // cout << b.queryWord("boy") << endl; ifstream in("input.txt"); string filename; string line; if(in) // 有该文件 { int i=1; while (getline (in, line)) // line中不包括每行的换行符 { //将int转string stringstream stream; //声明一个stringstream变量 int n; string str; stream << i; //向stream中插入整型数1234 stream >> str; //将int转string // istringstream f(line); // std::vector<std::string> strings; // string s; // while (std::getline(f, s, ' ')) // { b.storeWord(line,str); //} i++; } } // else // 没有该文件 // { // cout <<"no such file" << endl; // } // b.levelOrder(b.root); cout << b.queryWord("boy") << endl; system("pause"); return 0;}
下面是版本二:
#include <stdio.h>#include<iostream>#include<string.h>using namespace std;#include <stdio.h>#include<string.h>#include <iostream> #include <cstdlib>#include <cstdio>#include <stack> #include <string>#include <fstream> #include <sstream>#include <iostream>#include <vector>using namespace std; class BinaryTreeNode//树的节点类{public: BinaryTreeNode() { } //BinaryTreeNode(char c, BinaryTreeNode* left, BinaryTreeNode* right) { data = c; leftChild = left; rightChild = right; } char nodeChar; string rownum ; BinaryTreeNode *BinaryTreeNodes[26];};class Node //队列类中用链表存{public: BinaryTreeNode *data; Node *next; Node() { next = NULL; } Node(BinaryTreeNode *item, Node* link = NULL) { data = item; next = link; }};//队列类,作为层次遍历的辅助数据结构用class LinkQueue{private: Node *front, *rear;public: LinkQueue() { rear = front = new Node; }; bool empty() { return front == rear; } void outQueue(BinaryTreeNode * &e)//出队列 { Node *tmpPtr = front->next; e = tmpPtr->data; front->next = tmpPtr->next; if (rear == tmpPtr) rear = front; delete tmpPtr; } void inQueue(BinaryTreeNode * &e)//入队列 { Node *tmpPtr = new Node(e); rear->next = tmpPtr; rear = tmpPtr; }};//二叉树类class BinaryTree{public: BinaryTree() { root = 0; } //下面是接收一个单词储存到树中的方法 void storeWord(BinaryTreeNode* t,string word ,string rownum) { cout << word<< endl; //求字符地址,方便将该字符放入到26叉树中的哪一叉中 int k = word[0] - 'a'; cout<<k<<endl; cout<<(t->BinaryTreeNodes[k]==NULL)<< endl; //如果该叉树为空,则初始化 if (t->BinaryTreeNodes[k]==NULL) { cout<<4<<endl; t->BinaryTreeNodes[k] = new BinaryTreeNode(); cout<<3<<endl; //记录下字符 cout<<2<<endl; if(word.length() ==1) { t->BinaryTreeNodes[k]->rownum = rownum; return; } } else if(t->BinaryTreeNodes[k]!=NULL) { cout<<5<<endl; t->BinaryTreeNodes[k] = new BinaryTreeNode(); //记录下字符 cout<<6<<endl; if(word.length() ==1) { t->BinaryTreeNodes[k]->rownum = rownum; cout<<7<<endl; return; } } string nextWord = word.substr(1); //说明是最后一个字符,统计该词出现的次数 storeWord(t->BinaryTreeNodes[k],nextWord, rownum); } // 下面的方法用来查询一个单词返回单词的行号 string queryWord(string word) { } void levelOrder(BinaryTreeNode* t)//层次遍历 { } // void preOrderForCount(BinaryTreeNode* t)//用了前序遍历的方法来计算二叉树节点数目 // { // if (t) // { // count++; // preOrderForCount(t->leftChild); // preOrderForCount(t->rightChild); // } // } // int height(BinaryTreeNode* t)//返回一个节点的高度 // { // if (!t) return 0; // int heightLeft = height(t->leftChild); // int heightRight = height(t->rightChild); // if (heightLeft > heightRight) return ++heightLeft; // else return ++heightRight; // } // int size()//返回二叉树节点数目 // { // count = 0; // preOrderForCount(root); // return count; // } BinaryTreeNode* root; int count ;};int main(){ BinaryTree b; b.root = new BinaryTreeNode(); // b.storeWord("boy","3"); // b.storeWord("boyfriend","4"); // b.levelOrder(b.root); // cout << b.queryWord("boy") << endl; ifstream in("input.txt"); string filename; string line; if(in) // 有该文件 { int i=1; while (getline (in, line)) // line中不包括每行的换行符 { //将int转string stringstream stream; //声明一个stringstream变量 int n; string str; stream << i; //向stream中插入整型数1234 stream >> str; //将int转string // istringstream f(line); // std::vector<std::string> strings; // string s; // while (std::getline(f, s, ' ')) // { b.storeWord(b.root,line,str); //} i++; } } // else // 没有该文件 // { // cout <<"no such file" << endl; // } // b.levelOrder(b.root); system("pause"); return 0;}
0 0
- 字典树简介、应用以及与哈希表的比较
- 字典树的C++实现以及应用
- 哈希表Hashtable与字典表Dictionary<K,V>的比较。
- 数组与字典的应用
- 字典树简介和简易应用
- 字典树应用(1)字典树简介
- trie tree 字典树的简介与实现
- 字典树的应用
- 字典树的应用
- 字典(trie)树的应用与实现
- 传智播客Java web之 Servlet简介以及B/S与C/S的比较
- 字典树(trie)简介以及两种实现
- python中字典的操作与应用
- 简介REST,以及RESTful的小应用!
- Redis的字典与ConcurrentHashMap的扩容策略比较
- Junit的简介与应用
- Session的简介与应用
- 批处理的应用与简介
- 南阳理工acm 219 An problem about date(蔡勒公式)
- 带动画的圆形进度条
- MySQL数据库备份与恢复
- JavaScript执行环境和作用域链
- SpringMVC实践指南-第一集
- 字典树简介、应用以及与哈希表的比较
- SwitchCompat使用小结
- 我为什么注册 CSDN,而又不用?
- 学习贝叶斯
- 一个数组实现两个栈
- android学习—添加/删除module,xutils的添加
- Android Edittext 的 回车监听
- 三个在电脑上运行很有趣的程序
- html+css:按钮上显示消息数量精简代码