C语言实现二叉树-利用二叉树统计单词数目
昨天刚参加了腾讯2015年在线模拟考;
四道大题的第一题就是单词统计程序的设计思想;
为了记住这一天,我打算今天通过代码实现一下;
我将用到的核心数据结构是二叉树;
(要是想了解简单二叉树的实现,可以参考我的另一篇文章:http://www.cnblogs.com/landpack/p/4783120.html)
Problem
我需要统计的单词是在程序直接硬编码的;
这样做得原因是省略了文件输入输出所带来的困惑;
我的每篇文章,一般只说一个主题;
这样也方便我日后复习;
Solution
首先,我们需要定义一个结构体,如下代码所示:
const int LONGEST_WORD = ; // The longest word size struct binary_tree {
char str[LONGEST_WORD];
int count;
struct binary_tree * left;
struct binary_tree * right;
}; typedef struct binary_tree node;
注意到,我们假设最长的单词定义为一个常量,在这里我觉得目前32这个长度应该可以啦;
如果要统计的文章是化学论文,建议你再加大数字,因为化学式通常都很长;
然后是,我们的结构体;这应该很容易理解的;
由于C语言没有提供我想要的BOOL类型,因此自己动手写啦下面的代码;
这个定义非常有用,通常它比define更加值得推荐;
enum BOOL {
NO,
YES
}; typedef enum BOOL BOOL;
接下来,我们需要知道单词之间是如何比较大小的;
因此,需要一个函数叫做cmp;
代码实现如下:
BOOL cmp(char * s, char * t)
{
int i;
for (i = ; s[i] == t[i]; i++)
if ( s[i] == '\0' )
return NO;
return (s[i] - t[i]) < ? NO:YES;
}
同时遍历两个字符串,然后对返回值进行一个处理;
这样只会返回两种情况NO/YES,不然的话会返回三种值(-1,0,正数);
那样的话,不利于我们往后的工作;
接下来呢,就是如果返回YES我们该(如何) (做什么);
如果返回NO我们又该(如何)(做什么);
因此,我们需要一个insert函数,把数据的两种不同分别插入左右子树;
void insert(node ** tree, char * val) {
node * temp = NULL;
if(!(*tree)) {
temp = (node*)malloc(sizeof(node));
temp->left = temp->right = NULL;
temp->str = val; //issue code ...
temp->count = ;
*tree = temp;
return ;
} if(cmp(val, (*tree)->str)) {
insert(&(*tree)->left,val);
}else if (cmp(val,(*tree)->str)) {
insert(&(*tree)->right,val);
}else{
(*tree)->count++;
}
}
这段代码和前面提到的(C语言实现二叉树)里面的代码几乎一样的,哪里有详细介绍;
这里主要讲解一下注释有issue code的那行,如果这行不修改,程序将会蹦溃;
但是,我会故意不马上修改它,继续往下写;
我们需要一个函数,销毁节点:
void deltree(node * tree) {
if(tree) {
deltree(tree->left);
deltree(tree->right);
free(tree);
}
}
为了查看我们的结果,我们需要一种遍历方式;
这里我们就选择中序吧!
void print_inorder(node * tree) {
if(tree) {
print_inorder(tree->left);
printf("[%s\t\t\t]count:[%d]\n",tree->str,tree->count);
print_inorder(tree->right);
}
}
我们把头文件stdio.h/stdlib.h引入后;
把主int main(int argc, char ** arg{
node * root;
node * tmp;
//int i; root = NULL;
/* Inserting nodes into tree */
insert(&root,"hello");
insert(&root,"hey");
insert(&root,"hello");
insert(&root,"ok");
insert(&root,"hey");
insert(&root,"hey");
insert(&root,"hey"); printf("In Order Display\n");
print_inorder(root);/* Deleting all nodes of tree */ deltree(root);
}
gcc编译运行得到如下结果:
果然,我们的issue code有问题,原因是字符串不能像其他的,例如int类型一样直接用‘=’号赋值;
所以我们需要一个cpy函数:
void mystrcpy(char *s, char *t)
{
while ((*s++ = *t++) != '\0')
;
}
所有代码如下:
#include <stdio.h>
#include <stdlib.h> const int LONGEST_WORD = ; // The longest word size struct binary_tree {
char str[LONGEST_WORD];
int count;
struct binary_tree * left;
struct binary_tree * right;
}; typedef struct binary_tree node; enum BOOL {
NO,
YES
}; typedef enum BOOL BOOL; BOOL cmp(char * s, char * t)
{
int i;
for (i = ; s[i] == t[i]; i++)
if ( s[i] == '\0' )
return NO;
return (s[i] - t[i]) < ? NO:YES;
}
void mystrcpy(char *s, char *t)
{
while ((*s++ = *t++) != '\0')
;
} void insert(node ** tree, char * val) {
node * temp = NULL;
if(!(*tree)) {
temp = (node*)malloc(sizeof(node));
temp->left = temp->right = NULL;
//temp->str = val; //issue code ...
mystrcpy(temp->str,val);
temp->count = ;
*tree = temp;
return ;
} if(cmp(val, (*tree)->str)) {
insert(&(*tree)->left,val);
}else if (cmp(val,(*tree)->str)) {
insert(&(*tree)->right,val);
}else{
(*tree)->count++;
}
} void deltree(node * tree) {
if(tree) {
deltree(tree->left);
deltree(tree->right);
free(tree);
}
} void print_inorder(node * tree) {
if(tree) {
print_inorder(tree->left);
printf("[%s\t\t\t]count:[%d]\n",tree->str,tree->count);
print_inorder(tree->right);
}
} int main(int argc, char ** argv)
{
node * root;
node * tmp;
//int i; root = NULL;
/* Inserting nodes into tree */
insert(&root,"hello");
insert(&root,"hey");
insert(&root,"hello");
insert(&root,"ok");
insert(&root,"hey");
insert(&root,"hey");
insert(&root,"hey"); printf("In Order Display\n");
print_inorder(root); /* Deleting all nodes of tree */ deltree(root);
}
最后运行结果如下:
Discussion
那么这个程序已经完成啦!
还有很多可以优化的,也可以增加更多的功能;
例如,查找特定字符出现的次数;
或者特定字符所出现的行数,等等都可以;
我们会在日后慢慢完善;
See Also
无;
C语言实现二叉树-利用二叉树统计单词数目的更多相关文章
- SDUT OJ 数据结构实验之二叉树三:统计叶子数
数据结构实验之二叉树三:统计叶子数 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem Descr ...
- SDUT 3342 数据结构实验之二叉树三:统计叶子数
数据结构实验之二叉树三:统计叶子数 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 已知二叉 ...
- SDUT-3342_数据结构实验之二叉树三:统计叶子数
数据结构实验之二叉树三:统计叶子数 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 已知二叉树的一个按先序遍历输入的字符 ...
- 第六章 第一个Linux驱动程序:统计单词个数
现在进入了实战阶段,使用统计单词个数的实例让我们了解开发和测试Linux驱动程序的完整过程.第一个Linux驱动程序是统计单词个数. 这个Linux驱动程序没有访问硬件,而是利用设备文件作为介质与应用 ...
- 《征服c指针》学习笔记-----统计文本单词数目的程序word_count
1.程序的要求:对用户指定的英文文本文件(包括标准输入),将英文单词按照字母顺序输出到用户指定的文本文件中(包括标准输出),并且在各单词后面显示单词的出现次数. 2.模块设计: 主要分为:1.从输入流 ...
- C++读取文件统计单词个数及频率
1.Github链接 GitHub链接地址https://github.com/Zzwenm/PersonProject-C2 2.PSP表格 PSP2.1 Personal Software Pro ...
- 【二叉树】二叉树常用算法的C++实现
常见算法有: 1.求二叉树的最大深度 2.求二叉树的最小深度 3.二叉树的层次遍历 4.二叉树的前序遍历 5.二叉树的中序遍历 6.二叉树的后序遍历 7.求二叉树的节点个数 8.求二叉树的叶节点个数 ...
- 使用bash关联数组统计单词
使用bash关联数组统计单词 从bash 4开始支持关联数组,使用前需要声明,即 declare -A map map[key1]=value1 map[key2]=value2 map=([key1 ...
- 大数据学习day32-----spark12-----1. sparkstreaming(1.1简介,1.2 sparkstreaming入门程序(统计单词个数,updateStageByKey的用法,1.3 SparkStreaming整合Kafka,1.4 SparkStreaming获取KafkaRDD的偏移量,并将偏移量写入kafka中)
1. Spark Streaming 1.1 简介(来源:spark官网介绍) Spark Streaming是Spark Core API的扩展,其是支持可伸缩.高吞吐量.容错的实时数据流处理.Sp ...
随机推荐
- Android WebView 实现缓存网页数据
WebView中存在着两种缓存:网页数据缓存(存储打开过的页面及资源),H5缓存(即AppCache). 将我们浏览过的网页url已经网页文件(css.图片.js等)保存到数据库表中 缓存模式(5种) ...
- [原创] Legato 8.1 oracle full backup skip 奇怪的问题处理过程 -- 非调度日期手工运行调度也不成功(skip)
转载请注明出处: http://www.cnblogs.com/fengaix6/p/4677024.html 作者:飄ぺ風 环境: a. Server: Legato 8.1.2, aix 6.1 ...
- 用T-sql 实现Oracle Connect by 的功能
; with subDepartment as ( select BesonDepartmentID, DepartmentName, ParentBesonDepartmentID, 1 as Hi ...
- POJ 3181 Dollar Dayz DP
f[i][j]=f[i-j][j]+f[i][j-1],结果很大需要高精度. //#pragma comment(linker, "/STACK:1024000000,1024000000& ...
- What he did
//记录组内成员具体完成工作情况,格式为:时间-事件-人物 2015-4-19 用户需求分析---主要由韩林编写,国旗,李春伟辅助编写,国旗发布文档至博客 2015-4-22 快速原型---由郭龙东完 ...
- HTTP请求响应对照表
1)请求(客户端->服务端[request]) GET(请求的方式) /books/java.html(请求的目标资源) HTTP/1.1(请求采用的协议和版本号) Accept: */*(客户 ...
- Echarts动态加载后台数据
注意:1.用Ajax请求获取后台数据 2.Echarts只能处理Json数据 后台Controller:根据业务需求不同而返回不同数据,我前台要循环遍历Echarts的series进行数据添加,所以后 ...
- ios initialize和init等方法
在程序运行过程中,创建多个类对象,只会调用一次initialize [ɪˈnɪʃəˌlaɪz] .而创建几个类对象就会调用几次init; 创建一个类aa,分别重写 initialize和init方法 ...
- git的一些指令
1.这是一篇git.github相关具体操作的连接 http://www.cnblogs.com/fanyong/p/3424501.html 2. git remote -v 查看远程分支 git ...
- JAVA程序提示错误:需要class,interface或enum解决方法
错误详情: 解决办法:主要是用非记事本编写代码文件,存在编码格式转换问题.重新先建一个记事本程序,然后把源代码粘贴到该文件下,用javac 类名.java编译,java 文件名运行该程序即可