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

题目要求:

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
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值