彻底理解指针第五篇


  这个题目是对之前的改进:统计输入中所有单词的次数。
  因为单词不能顺序,也不能对输入的每一个单词进行线性查找,这样复杂度O(n*n)所以此题联想到用二叉树,高校的查找树。  二叉树是递归的经典算法: 1.递归先要搞明白递归过程。  2.递归出口  3.递归返回  对于此题来说,递归过程很简单,递归出口就是单词没有在树中的时候,递归返回,在 递归调用结束之后,层层返回。   对于此要解决好以下方面:  1.每次查找都要从root开始  2.每次调用函数addtree(),最后的返回值都是根root,也就是root永远指向根结点  3.理解好每一次递归调用和递归返回。  
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define BUFSIZE 100
#define MAXWORD 100
struct node{
	char *word;//指向单词的指针
	int count;//单词出现的次数
	struct node *left;
	struct node *right;
};
char buf[BUFSIZE];//用于xieungetch函数的缓冲区
int bufp=0;//buf中下一个空间的位置
//调用xiegetch和xieungetch,用来确定程序它已经读入的输入是否足够
//读取下一个待处理的字符
//这样,此后在调用xiegetch函数时,在读入新的输入之前先返回ungetch函数放回的那个字符
int xiegetch(void)
{
    return (bufp > 0) ? buf[--bufp] : getchar();
}
//xieungetch函数则用于把字符放回到输入中
//xieungetch函数把要压回的字符放到一个共享缓冲区(字符数组)中,当该缓冲区不空时,xiegetch函数就从
//缓冲区中读取字符;当缓冲区为空时,xiegetch函数调用getchar函数直接从输入中读字符
void xieungetch(int c)
{
  if (bufp >= BUFSIZE)
    printf("ungetch: too many characters ");
  else
   buf[bufp++] = c;
}
//读取输入的下一个单词,返回值分为
//单词首字母,EOF,第一个字符(不是字母)
int getword(char *p,int lim)
{
	char c;
	//w和p指向同一个数组,方便操作
	char *w=p;
	while(isspace((c=xiegetch())))
		;
	if(c!=EOF)
		*w++=c;
	//判断第一个首字母,然后返回第一个字符
	//可能是EOF或者不是字母的字符
	if(!isalpha(c))
	{	
		*w='\0';
		return c;
	}
	//判断剩下的字符
	for(;--lim>0;w++)
		if(!isalnum(*w=xiegetch()))
		{
			xieungetch(*w);
			break;
		}
	*w='\0';
	//返回首字母
	return *p;
}
//将新单词复制到某个位置
char *strdupp(char *s)
{
	char *p;
	p=(char *)malloc(strlen(s)+1);
	if(p!=NULL)
		strcpy(p,s);
	return p;
}
//在P的位置或者P的下方增加一个W节点
struct node *addtree(struct node *p,char *w)
{
	int cond;
	//递归调用出口
	if(p==NULL)
	{	
		p=(struct node *)malloc(sizeof(struct node));
		p->word=strdupp(w);
		p->count=1;
		p->left=p->right=NULL;
	}
	else if((cond=strcmp(w,p->word))==0)
		p->count++;
	else if(cond<0)
		p->left=addtree(p->left,w);
	else
		p->right=addtree(p->right,w);
	//递归调用结束,一层一层返回到根节点
	return p;
}
//中序打印
void treeprint(struct node *p)
{
	if(p!=NULL)
	{
		treeprint(p->left);
		printf("%4d %s\n",p->count,p->word);
		treeprint(p->right);
	}
}
int main()
{
	struct node *root;
	root=NULL;
	char word[MAXWORD];
	//root永远指向根节点
	while(getword(word,MAXWORD)!=EOF)
		if(isalpha(word[0]))
			root=addtree(root,word);
	treeprint(root);
	return 0;
}








































  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值