完整工程

https://download.csdn.net/download/renzemingcsdn/21378979

需求

在这个作业中,你将从一个大文本文件中找到100个最经常出现的单词。程序必须用C语言实现。一个连续的字符串A… z . A…Zz,可能带有撇号’,被认为是一个单词。大写字母和小写字母被认为是相等的。程序应打印100个最经常出现的单词及其频率。这些单词按其频率的降序排列因为文件可能非常大,所以需要合适的数据结构来存储单词及其频率。例如,它可以是一个哈希表或二叉搜索树。您可以通过使用一些快速算法对结构进行排序来找到最频繁的单词。

原理

采用二叉搜索树统计频率,快速排序找到最多的单词。

//https://www.cnblogs.com/landpack/p/4787004.html
//http://data.biancheng.net/view/71.html

实现

main.c中,读取文件,每读取一个单词,将其插入二叉搜索树,而后进行快速排序,最后输出单词。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>#include "readtxt.h"
#include "binarytree.h"#define INFILE "./Test/Bulk.txt"
#define OUTFILE "./outtest.txt"int total_num=0;
int main()
{//printf("Hello world!\n");FILE *fp_in, *fp_out;char str[LONGEST_WORD];if((fp_in=fopen(INFILE,"r"))==NULL){printf("\nCannot open in file strike any key exit!");return -2;}if((fp_out=fopen(OUTFILE,"w"))==NULL){printf("\nCannot open out file strike any key exit!");return -3;}node * root;root = NULL;while(getWord(fp_in,str)==1){total_num++;insert(&root,str);}QSort(words,1,total_difrent_num);fputs( "Total number of words = ", fp_out);fprintf(fp_out , "%d\n" , total_num );fputs( "Number of different words = ", fp_out);fprintf(fp_out , "%d\n" , total_difrent_num );fputs( "The 100 most common words:\nWORD            NUMBER OF OCCURRENCES\n",fp_out);for(int i=1;i<=100;i++){fputs( words[i]->str, fp_out);fputs( "             ", fp_out);fprintf(fp_out , "%d\n" , words[i]->count );//printf("[%s]count:[%d]\n",words[i]->str,words[i]->count);}//deltree(root);fclose(fp_out);fclose(fp_in);return 0;
}

binary_tree,h
有个测试用例中,单词长度达到69,所以字符串开大一点

#ifndef BINARYTREE_H_INCLUDED
#define BINARYTREE_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LONGEST_WORD  73    // 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;
extern int total_difrent_num;
extern node* words[];
int cmp(char * s, char * t);
void insert(node ** tree, char * val);
void deltree(node * tree);
void print_inorder(node * tree);
#endif // BINARYTREE_H_INCLUDED

binarytree.c 注意比较函数的写法,返回0,1,-1分别代表相等、大于、小于。

#include "binarytree.h"
int total_difrent_num=0;
node* words[3000000];
int cmp(char * s, char * t)
{int i=0;while(t[i]!='\0' && s[i]!='\0' && s[i]==t[i]){i++;}if(s[i]==t[i])//都结束了return 0;if(s[i]<t[i])return -1;return 1;
}void insert(node ** tree, char * val) {node * temp = NULL;if(!(*tree)) {temp = (node*)malloc(sizeof(node));temp->left = temp->right = NULL;strcpy(temp->str , val);temp->count = 1;*tree = temp;total_difrent_num++;words[total_difrent_num]=temp;return ;}int ret=cmp(val, (*tree)->str);if(ret==1) {//val大于strinsert(&(*tree)->right,val);}else if (ret==-1) {//str大于valinsert(&(*tree)->left,val);}else{(*tree)->count++;}
}
void deltree(node * tree) {if(tree) {deltree(tree->left);deltree(tree->right);free(tree);}
}
//中序遍历
void print_inorder(node * tree) {printf("In Order Display\n");if(tree) {print_inorder(tree->left);printf("[%s\t\t\t]count:[%d]\n",tree->str,tree->count);print_inorder(tree->right);}
}

quick_sort.h

#ifndef QUICKSORT_H_INCLUDED
#define QUICKSORT_H_INCLUDED
#include "binarytree.h"
void swap(node **a,node **b);
#endif // QUICKSORT_H_INCLUDED

quicksort.c 注意交换函数,交换的是words[]中的指针,不要交换node数据,不然开销太大。也就是,依据node->count排序,交换node*,数据始终不动

#include <stdio.h>
#include <stdlib.h>#include "binarytree.h"
#include "quicksort.h"
void swap(node **a,node **b){node* tmp=*a;*a=*b;*b=tmp;
}
//此方法中,存储记录的数组中,下标为 0 的位置没有数据,不放任何记录,记录从下标为 1 处开始依次存放
int Partition(node **L,int low,int high){L[0]=L[low];//零位置是缓冲区int pivotkey=(*L[low]).count;//目标值while (low<high) {//直到两指针相遇,程序结束while (low<high && (*L[high]).count<=pivotkey) {high--;//high指针左移,直至遇到比pivotkey值小的记录,指针停止移动}L[low]=L[high];//直接将high指向的小于支点的记录移动到low指针的位置。while (low<high && (*L[low]).count>=pivotkey) {low++;//low 指针右移,直至遇到比pivotkey值大的记录,指针停止移动}L[high]=L[low];//直接将low指向的大于支点的记录移动到high指针的位置}L[low]=L[0];//将支点添加到准确的位置return low;
}
void QSort(node *L,int low,int high){if (low<high) {int pivotloc=Partition(L, low, high);//找到支点的位置QSort(L, low, pivotloc-1);//对支点左侧的子表进行排序QSort(L, pivotloc+1, high);//对支点右侧的子表进行排序}
}

二叉搜索树+快速排序 查到文本中出现频率最多的100个词 【留学生作业】相关推荐

  1. 173. 二叉搜索树迭代器/94. 二叉树的中序遍历/145. 二叉树的后序遍历/98. 验证二叉搜索树

    2020-05-12 1.题目描述 二叉搜索树迭代器 2.题解 对于二叉搜索树而言,进行中序遍历就可以得到其有序序列,我们可以先对树进行遍历,将结果保存在 vector中,然后进行计算即可. 3.代码 ...

  2. 算法基础知识科普:8大搜索算法之二叉搜索树(中)

    昨天图文介绍了二叉搜索树的基本概念,本篇图文介绍二叉搜索树的具体实现.既然二叉搜索树是二叉树的特殊应用,所以我们首先封装二叉树的结点,即数据-左子树-右子树,然后实现ISymbolTalbe接口中的方 ...

  3. 动态展示二叉搜索树之实践进行时

    目录 一.选题展示 二.思考题目 三.阶段一:图形显示二叉搜索树之插入 1.图形显示二叉搜索树的要求 2.原博主的代码和输出 四.阶段二:图形显示二叉搜索树之查删 1.二叉搜索树的查找操作 2.二叉搜 ...

  4. L3-010. 是否完全二叉搜索树

    L3-010. 是否完全二叉搜索树 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 将一系列给定数字顺序插入一个初始为空的二叉搜 ...

  5. 数据结构与算法 整理笔记---二叉搜索树

    二叉搜索树 查找问题是计算机中非常重要的基础问题 二分查找法 对于有序数组,才能使用二分查找法(排序作用) public class BinarySearch {public static int b ...

  6. 算法篇 - 二叉搜索树

    前言 在前端的工作当中,二叉搜索树不怎么常见,虽然没有快排.冒泡.去重.二分.希尔等算法常见,但是它的作用,在某些特定的场景下,是非常重要的. 目前es6的使用场景比较多,所以我准备能用es6的地方就 ...

  7. [剑指offer][JAVA]面试题第[33]题[二叉搜索树的后序遍历][单调栈][递归分治]

    [问题描述][中等] 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果.如果是则返回 true,否则返回 false.假设输入的数组的任意两个数字都互不相同.参考以下这颗二叉搜索树:5/ ...

  8. 天梯赛-是否完全二叉搜索树

    将一系列给定数字顺序插入一个初始为空的二叉搜索树(定义为左子树键值大,右子树键值小),你需要判断最后的树是否一棵完全二叉树,并且给出其层序遍历的结果. 输入格式: 输入第一行给出一个不超过20的正整数 ...

  9. 二叉搜索树相关知识及应用操作

    文章目录 概念 查找二叉搜索树的第k大节点 概念 二叉查找树(Binary Search Tree),(又名:二叉搜索树,二叉排序树)--它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不 ...

最新文章

  1. 基于开源Flash Server:Red5构建RTMP流媒体播放平台
  2. JS判断是否为安卓orIOS
  3. 元宇宙“众声喧哗”,三季度财报超预期的欢聚能否分一杯羹?
  4. sqlite导入后无法使用
  5. 资源权限操作-查询所有资源权限
  6. 如何从特定位置开始分享YouTube视频
  7. Java lambda expression
  8. Oracle数据库启动以及说明
  9. Docker监控方案之cAdvisor
  10. 基于JAVA+SpringMVC+Mybatis+MYSQL的实习生招聘网站
  11. Linux 内核源码(kernel source)路径
  12. linux ssh证书登录
  13. [CSS]关于Flexbox
  14. 使用dnsmasq让本地hosts泛解析
  15. 离散域下的泊松方程求解(python实现)
  16. 【qq机器人】不良语言撤回
  17. 图灵奖得主(麦卡锡\霍尔)
  18. 新员工如何快速融入新的工作环境
  19. 启动redis失败 Could not create server TCP listening socket 127.0.0.1:6379: bind: 操作成功
  20. linux利用su -从普通用户切换root权限

热门文章

  1. 编程语言的语法与语义
  2. Servlet--HttpSession接口,HttpSessionContext接口,Cookie类
  3. VMware OVF 协议
  4. 图像处理(MATLAB及FPGA)实现基础原理(持续更新)
  5. TPLINK-WR720N刷openwrt
  6. linux vim 粘贴 没有保持原来的格式,linux中的剪贴板用法,实现vim中原格式粘贴...
  7. asp.net c# 常见面试试题总结汇总(含答案)
  8. 虚拟主机搬迁服务器要重新备案吗,域名更换虚拟主机要重新备案吗
  9. extjs java 教程,JAVA开发工具 - 在IntelliJ IDEA下开发ExtJS应用指南
  10. gFTP不能显示中文文件(夹)名的解决方法