二叉树实现单词统计及排序(c++版)

这是面向对象程序设计实验任务中的一道题
题目要求是这样的:
本题是关于二叉树的应用题。二叉树的结点类型(Tnode)已经给出,其中 left和right分别指向当前结点的左孩子和右孩子(这是树结点的构成要素),word和count用于存储应用数据,分别存储一个单词的文本、该单词在输入中出现的次数,这就意味着不同结点中存储的 word 值不能相同。

如果你对二叉树操作比较熟练,这题肯定不难。不过来看这篇博客的我觉得对于二叉树的认识总是有些不够的。这里通过我对这道题的求解,可以一起学习。
首先我们知道需要创建数据对象,包括左右指针,包含字符串对象,包含整型变量名统计单词数。

struct Tnoded
{	
	string word;
	//这里使用c++中的string库,直接使用字符串对象,不熟的建议自己学习一下
	
	int cunt=1;  
	//为与关键字count重复这里用cunt统计单词数
	
	Tnoded *left;
	Tnoded *right;
};

然后这里最关键的就是如何进行输入,输入后如何存放的问题。
在这里我们用这样一个思路,先将第一个单词放入第一个节点。后续输入的单词与当前节点单词进行比较,比它大放到右边,比他小放在左边。先贴上代码,注释放在代码里面。

void input_new_word(Tnoded * pt)
{
    Tnoded *pd=pt;//需要进行递归遍历,首先需要一个存放新单词的节点,然后需要一个指向当前位置的指针
    /*******先存放第一个节点**********/
    cin >> pt->word;//便于循环中比较的统一性
    pd=pt;//都指向第一个节点  
    string com=" ";
    for(int i=1;;i++)
     {
        Tnoded *new_word=new Tnoded;
        cin >> new_word->word;
        com=new_word->word;
        if(com.compare(".")==0)
        	break;
        new_word->left=new_word->right=NULL;//使新单词始终指向空
        while(1)
        {
 /***********这里有个问题就是好像string类型不能使用trcmp函数进行比较************/
            if(new_word->word.compare(pd->word)<0)//新单词比父节点单词小
            //这里我们使用compare函数,具体方法可以自己网上查阅,这里不多解释
            {
                if(pd->left==NULL)//pd的左孩子是空,就可以将其存放在这个位置
                {
                    pd->left=new_word;
                    pd=pt;//仍然让pd指向头节点,因为后续插入还要从头节点往下比较,这里多思考一下
                    break;//此时这个节点存好了,跳出此次循环,进行下一个单词的输入和存放
                }
                else
                {
                    Tnoded *p=pd->left;
                    pd=p;//此时pd指向下面左,还没存好,没有找到位置,这个时候不能让pd指向头节点,
                         //否则之前比较的都白费了,这个后面还有类似的,自己想清楚
                }
            }
            else if(new_word->word.compare(pd->word)==0)
            {
                pd->cunt++;//单词相同时数目加1
                pd=pt;
                break;
            }
            else if(new_word->word.compare(pd->word) > 0)
            {
                if(pd->right==NULL)//pd的左孩子是空,就可以将其存放在这个位置
                {
                    pd->right=new_word;
                    pd=pt;
                    break;//此时这个节点存好了
                }
                else
                {
                    Tnoded *p=pd->right;
                    pd=p;//此时pd指向下面左,还没存好,没有找到位置
                }
            }
        }
    }while(cin >>a);
    //这种方法通用可以控制输入结束标志,最后ctrl+z输入结束
}

在上面的代码中,有几点值得学习,while控制循环结束,compare函数的使用,以及如何将单词存入

//**中序遍历输出**
//这里输出使用递归,自己看,书上网站上很多,也不是很难理解
void InOrger_output(Tnoded *T)
{
    if(T!=NULL)
    {
        InOrger_output(T->left);
        cout << T->word<< "="<< T->cunt << '\t';
        InOrger_output(T->right);
    }
}

最后就是一个main函数了

int main()
{
    Tnoded * head=NULL;
    head=new Tnoded;
    head->right=head->left=NULL;
    cout << "Please enter test data and press the '.' key to finish "<<endl;//输入‘.'结束输入
    input_new_word(head);
    cout << "从小到大输出二叉树中的单词"<<endl;
    InOrger_output(head);
    return 0;
}

最后你只需要将代码拼接起来就可以了。分开放完全是为了做一些解释。

给个赞吧!谢谢!

  • 12
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值