C/C++语言实现二叉树统计单词

自做代码1:手动输入

/*
2020/4/5
C语言实现:手动输入一个个单词
使用二叉树统计单词的个数
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

/*
使用枚举定义BOOL类型
*/
enum BOOL
{
	NO,YES
};//此时C语言中enum BOOL为一个类型
typedef enum BOOL BOOL;

/*
定义树
*/
typedef struct Node
{
	char word[30];
	int count;
	struct Node* lchild;
	struct Node* rchild;
}Node,*Tree;

void insert(Tree *root,char *word)//root的指向发生改变需要使用指针void insert(Node **root,char *word)
{
	Node* tmp = NULL;
	if( !(*root) )
	{
		tmp = (Node*)malloc(sizeof(Node));
		strcpy(tmp->word,word);
		tmp->count = 1;
		tmp->lchild = tmp->rchild = NULL;
		*root = tmp;//此处需要修改指针的指向
		return ;
	}

	if(strcmp((*root)->word,word)>0)//搜索二叉树,左子树<=根节点,右子树>根节点
	{
		insert(&(*root)->lchild,word);
	}
	else if(strcmp((*root)->word,word) <0)
	{
		insert( &(*root)->rchild,word);
	}
	else
		(*root)->count++;
}

void preOrder(Tree root)
{
	if(root)
	{
		printf("%s %d\n",root->word,root->count);
		preOrder(root->lchild);
		preOrder(root->rchild);
	}
}


int main()
{
	Tree root = NULL;
	insert(&root,"bbb");
	insert(&root,"aaa");
	insert(&root,"bbb");
	insert(&root,"ccc");
	insert(&root,"aaa");
	preOrder(root);	
	return 0;

}
/*
bbb 2
aaa 2
ccc 1
*/

自做代码2:从标准输入中输入

//第一次编写
/*
2020/4/6
C语言实现二叉树进行单词统计:从标准输入中输入单词
C程序设计语言(略作改动)
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>

#define MAXWORD 100

struct Node
{
	char word[MAXWORD];//原文是char *word;比较麻烦
	int count;
	struct Node* lchild;
	struct Node* rchild;
};

/*
获得单词或者字符保存到word中
返回值单词首字母,EOF,非字母字符
*/
int getword(char *word,int lim)
{
	int c;
	char* w = word;

	while( isspace(c = getchar()))
		;
	if(c != EOF)
		*w++ = c;
	if( !isalpha(c))//第一个字符是否是字母
	{
		*w = '\0';//单个非字母的数字保存到w中
		return c;//返回非字母字符、EOF
	}

	for(;lim--;w++)
	{
		if(!isalnum( *w = getchar()) )
		{
			ungetc(*w,stdin);//stdin就是标准输入流,可以直接使用
			break;
		}
	}
	*w = '\0';
	return w[0];
}

struct Node* insert(struct Node* root,char* word)//指针的指向有可能发生改变,可以通过返回值修改
{
	int condition;
	if(root == NULL)
	{
		root = (struct Node*)malloc(sizeof(struct Node));
		strcpy(root->word,word);
		root->count = 1;
		root->lchild = root->rchild = NULL;
		//return root;//返回值写在这里是有问题的*********************
	}
	else
	{
		condition = strcmp(word,root->word);
		if(condition == 0)
			root->count++;
		else if(condition > 0)
			root->rchild = insert(root->rchild,word);
		else
			root->lchild = insert(root->lchild,word);
	}
	return root;//***************
	
}

void print(struct Node* root)
{
	if(root)
	{
		print(root->lchild);
		printf("%s\n",root->word);
		print(root->rchild);
	}
}
		

int main()
{
	struct Node* root;
	char word[MAXWORD];

	root = NULL;
	while( getword(word,MAXWORD) != EOF)
	{
		if(isalpha(word[0]))
		{
			root = insert(root,word);
		}
	}
	print(root);
	return 0;
}
/*
IN:
a perfect match between a man and a girl
^Z
OUT:
a 3
and 1
between 1
girl 1
man 1
match 1
perfect 1
*//
  • 自做代码2:从标准输入中输入
//第二次编写 C++
//C++实现
/*
*/
#include<stdio.h>
#include<ctype.h>
#include<string.h>//strcpy..memset()的头文件
#include<stdlib.h>//malloc的头文件

const int MAXWORD = 100;

typedef struct node
{
	char word[MAXWORD];
	int count;
	node* lchild;
	node* rchild;
}Node,*Tree;

/*
单词:以字母开头的字母和数字串,如a,aa,aa88均是单词
将单词或非空白字符(非字母)读入到word[]中
返回值:单词的首字母、EOF、非单词的单个字符
故可以通过返回值是否为字母判断该读取的word是否为单词
*/
int getword(char word[],int lim)
{
	/*
	char c;
	使用int c能够读入所有的输入,输入的范围更大
	*/
	int c;  
	char *w = word;
	
	/*
	去除所有的空白符 \n \t ' '
	*/
	while( isspace(c = getchar()))
		;

	/*
	判断第一个读入的字符是否需要存入word[]中,
	以及返回非单词的第一个字符
	*/
	if(c != EOF)
		*w++ = c;
	if(!isalpha(c))
	{
		*w = '\0';
		return c;
	}

	/*
	确定是单词
	继续读取单词后面的内容
	*/
	for( ; lim--;w++)
	{
		if(!isalnum(*w = getchar()))
		{
			ungetc(*w,stdin);//将多读入的单词返回到输入流中
			break;
		}
	}
	*w = '\0';
	return w[0];
}

/*
通过不断的插入节点来构建树
在此过程中root的指向会发生改变,
一次需要使用引用(在C++中)
*/
void insert(Node* &root,char word[])//c++中这里使用的是引用比较直观和方便
{
	if(root == NULL)
	{
		root = (Node*)malloc(sizeof(Node));
		root->count = 1;
		strcpy(root->word,word);
		root->lchild = root->rchild = NULL;
		return ;
	}

	int cmp = strcmp(root->word,word);
	if(cmp > 0)
	{
		insert(root->lchild,word);
	}
	else if(cmp == 0)
	{
		root->count++;
	}
	else
	{
		insert(root->rchild,word);
	}
}


/*
先序遍历,按照顺序从小到大输出
*/
void preOrder(Node* root)
{
	if(root)
	{
		preOrder(root->lchild);
		printf("%s %d\n",root->word,root->count);
		preOrder(root->rchild);
	}
}




int main()
{
	Node* root = NULL;
	char word[MAXWORD];
	while( getword(word,MAXWORD) != EOF)
	{
		if( isalpha(word[0]))
		{
			insert(root,word);
		}
	}
	
	preOrder(root);

	return 0;
}

自做代码3:从文件中输入

//这里就不在另外编写了,参见另外一篇文章,以题目的形式解决。交叉引用生成器

发布了117 篇原创文章 · 获赞 71 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_34686440/article/details/105335987