二叉树统计单词的个数,若单词第一次出现,则产生新的树节点

 

//二叉树统计单词的个数,若单词第一次出现,则产生新的树节点

 

#include <stdio.h>

#include <ctype.h>

#include <string.h>

#include <stdlib.h>

 

#define MAXWORD 100

 

struct tnode     //树的节点

{

       char *word;//指向单词的指针

       int count;//单词出现的次数

       struct tnode *left;//左子节点

       struct tnode *right;//右子节点

};

 

struct tnode *addtree(struct tnode * ,char * );

struct tnode *talloc(void);

char *strdup(char * );

void treeprint(struct tnode * );

int getword(char * ,int );

 

int  main(void)

{

       struct tnode *root;

       char word[MAXWORD];

 

       root = NULL;

       while(getword(word,MAXWORD)!= EOF)

       {

              if(isalpha(word[0]))

                     root=addtree(root, word);

       }

       treeprint(root);

       return 0;

}

/*在p的位置或p的下方增加一个w节点*/

struct tnode *addtree(struct tnode *p, char *w)

{

       int cond;

        if(p == NULL)

        {

               p=talloc();

               p->word = strdup(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 tnode *p)

{

       if (p !=NULL)

       {

              treeprint(p->left);

              printf("%4d  %s\n",p->count, p->word);

              treeprint(p->right);

       }

}

/*创建一个node节点*/

struct tnode *talloc(void)

{

       return (struct tnode * ) malloc(sizeof(struct tnode));//强制类型转换

}

/*复制s*/

char *strdup(char *s)

{

       char *p;

      

       p = (char *) malloc(strlen(s)+1);

       if (p != NULL)

              strcpy(p,s);

       return p;

}

 

/*getword从输入中读取下一个单词是以字母开头的字母和数字串,

也可以是以字母开头的字母和数字串,也可以是一个非空白字符串。

函数返回值可能是单词的第一个字符、文件结束符EOF或字符本身(如果该字符不是字母字符本身)*/

int getword(char *word, int lim)

{

    int c, getch(void);

    void ungetch(int);

    char *w = word;

    while (isspace(c = getch()))   //c跳过空白符

        ;

    if (c != EOF)

        *w++ = c;

    if (!isalpha(c))       //c不是字母

       {

        *w = '\0';

        return c;

    }

    for ( ; --lim > 0; w++)

       {

        if (!isalnum(*w = getch()))   //输入不是字母或数字时,该单词结束

              {

            ungetch(*w);

            break;

        }

       }

    *w = '\0'; //字符串结束符'\0'

    return word[0];      //返回值是单词的第一个字符

}

 

#define BUFSIZE 100   //缓冲区的大小

char buf[BUFSIZE];      //用于ungetchar函数的缓冲区

int bufp = 0;   //buf中下一个空闲位置

 

//读取一个字符(可能是压回的字符)

int getch(void)

{

    return (bufp > 0) ? buf[--bufp] : getchar();

}

 

//把字符压回到输入中

void ungetch(int c)  

{

    if (bufp >= BUFSIZE)

        printf("ungetch: too many characters\n");

    else

        buf[bufp++] = c;

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值