您的位置:首页 > 理论基础 > 数据结构算法

字典树简介、应用以及与哈希表的比较

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息