单词吸血鬼源代码 二叉树操作

来源:互联网 发布:中央民大附中知乎 编辑:程序博客网 时间:2024/05/08 04:39

/*****************************************************************
程序名:单词吸血鬼
作者:  常涛

GNU认证

  程序功能简介:可以提取出以ASCII码保存的文件中的单词并以字典顺序输出

*****************************************************************/

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>

struct node
{
   struct node *left;   /* tree to the left */
   struct node *right;  /* three to the right */
   char   *word;        /*  word for this tree */
};

/*the top of the tree */
static struct node *root=NULL;

/****************************************************
* 内存出错报警                                     *
****************************************************/

void memory_error(char* text)
{
   fprintf(stderr,text);
   exit(8);
}

/****************************************************
* save_string --将string保存到堆防止栈溢出.         *
*                                                   *
* 参数:                                            *
*        string -- 要存的字符串  .                  *
*                                                   *
* 返回值:                                          *
*      指针                                         *
****************************************************/


char *save_string(char *string)
{
   char *new_string;      /*初学者易犯的错误,对没有初始化的指针赋值*/

   new_string = malloc((unsigned)(strlen(string))+1);  //关键步骤,new和malloc一样,都是分配在堆的

   if(new_string == NULL)
   {
       memory_error("没有足够的内存用于分配");
   }

   strcpy(new_string, string);     //相当有用的函数

   return(new_string);             
}

/****************************************************
* enter -- 向树中加入一个值                         *
*                                                   *
* 参数                                              *
*      node -- 正在操作的树                         *
*      word -- 要输入的值                           *
****************************************************/

void enter(struct node **node, char *word)
{
   int result;                  /*暂存比较结果p*/

   char *save_string(char *);   /*s数据入堆*/
   /*
    * 如果满树开始建立新的内存块
   */

   if((*node) == NULL)
   {
       (*node) = malloc(sizeof(struct node));

       if((*node) == NULL)
       {
    memory_error("没有足够的内存用于分配");
    return;
       }

       (*node) -> left = NULL;              
       (*node) -> right = NULL;

       (*node) -> word = save_string(word);   //这步因该想办法理解它的好处

   }

   /* 选择数据保存的位置 */
   result = strcmp((*node) -> word, word);
  
   /*如果已经存在要存入的数据,则返回 */

   if(result == 0) return;
  
   /* 数据将会依据result的值来选择存储点 */

   if(result < 0)
   {
       enter(&(*node) -> right, word);
   }
   else
   {
       enter(&(*node) -> left,  word);
   }
}

/*****************************************************************
* scan -- 扫描并读入文件          .                              *
*                                                                *
* 参数:                                                         *
*       name -- 要读人的文件名和                                 *
*****************************************************************/

void scan(char *name)
{
   char word[100];            /*每次操作的数据*/
   int index=0;               /* 字符索引  */ 
   int ch = 0;                /* 当前字符r    */
   FILE *in_file;             /* 输入的文件指针           */

   in_file = fopen(name,"r");
   if (in_file == NULL)
   {
       fprintf(stderr,"Error:Unable to open %s/n", name);
       exit(8);
   }
   while(1)
   {
       while(1)
       {
    ch = fgetc(in_file);

    if(isalpha(ch) || (ch == EOF))
    {
        break;
    }
       }

       if(ch == EOF) break;

       word[0] = ch;
       for(index = 1; index < sizeof(word); ++index)
       {
    ch = fgetc(in_file);
    word[index]=ch;

    if(!isalpha(ch)) break;
       }
       word[index] = '/0';

       enter(&root,word);
   }

   fclose(in_file);
}

/*************************************************************
* print_tree -- 输出整个树                                   *
*                                                            *
* 参数                                                       *
*    top -- 要输出树的根节点                                 *
*************************************************************/

void print_tree(struct node *top)
{
   if(top == NULL) return;        /* 元树则返回 */
   print_tree(top -> left);
   printf("%s/n",top -> word);
   print_tree(top -> right);
}

int main(int argc, char *argv[])
{
 
   if(argc !=2)
   {
       fprintf(stderr,"错误:没有足够的参数/n");
       fprintf(stderr,"     在命令行窗口输入 /n");
       fprintf(stderr,"     用法如下:/n");
       fprintf(stderr,"     wordsvampire '文件名'(文件名因该是全称就是要有扩展名)/n");
       system("pause");
       exit(8);
   }
  
   scan(argv[1]);
   print_tree(root);
   system("pause");
   return(0);
}