字典树简介、应用以及与哈希表的比较
2017-05-04 22:07
375 查看
题目要求:
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; }
相关文章推荐
- Mysql常用命令简介以及应用实例
- Servlet简介 以及servlet一些细节 servletconfig servletcontext 的几个应用
- [Django]第二篇:MVC框架简介以及Django简单应用
- 目前网络上开源的网络爬虫以及一些简介和比较
- yaml简介以及在python上的应用
- 什么是中文分词以及中文分词的应用简介
- 字典树的基础,以及在实际项目中对于敏感词的替换的应用
- 简介REST,以及RESTful的小应用!
- 哈希表以及哈希的应用
- 数据结构(4)--循环链表的应用之约瑟夫环问题以及线性表总结之顺序表与链表的比较
- yaml简介以及在python上的应用
- ArrayList 与HashSet的比较,及应用反射读取properties配置文件中的数据进行实例化再调用,以及类加载器的使用;还有HashCode的分析,及导致内存泄露,内存溢出的原因之一
- ibatis的简介以及简单的应用实例
- Redis简介、与memcached比较、存储方式、应用场景、生产经验教训、安全设置、key的建议、安装和常用数据类型介绍、ServiceStack.Redis使用(1)
- yaml简介以及在python上的应用
- 三种条码code39和code93以及code128在应用中的比较
- YAML 简介以及在python上的应用
- 堆和哈希表的实现以及应用(一)
- hash应用以及vector的使用简介:POJ 3349 Snowflake Snow Snowflakes
- 视区相关单位vw, vh..简介以及可实际应用场景