《数据结构课程设计》预习日记

该文主要涉及三个信息技术领域的任务:一是设计并实现了一个图书信息管理系统,包括增删改查、快速排序等功能;二是使用A*算法解决九宫重排问题,寻找最优移动序列;三是利用线性表和二叉排序树统计英文文章单词频率,过滤低频词并输出结果。这三个任务展示了数据结构和算法在实际问题中的应用。
摘要由CSDN通过智能技术生成

目录

任务一 图书信息管理系统的设计与实现

一、实验要求

二、实验分析

数据结构

框架结构

三、代码实现

任务二 隐式图的搜索问题

一、实验要求

二、实验分析

数据结构

算法设计

三、代码实现

任务三 基于二叉排序树的低频词过滤系统

一、实验要求

二、实验分析

数据结构

         流程及算法设计

三、代码实现


任务一 图书信息管理系统的设计与实现

一、实验要求

设计并实现一个图书信息管理系统。根据实验要求设计该系统的菜单和交互逻辑,并编码实现增删改查的各项功能。 该系统至少包含以下功能:

  1. 根据指定图书个数,逐个输入图书信息;
  2. 逐个显示图书表中所有图书的相关信息;
  3. 能根据指定的待入库的新图书的位置和信息,将新图书插入到图书表中指定的位置;
  4. 根据指定的待出库的旧图书的位置,将该图书从图书表中删除;
  5. 能统计表中图书个数;
  6. 实现图书信息表的图书去重;
  7. 实现最爱书籍查询,根据书名进行折半查找,要求使用非递归算法实现,成功返回此书籍的书号和价格;
  8. 图书信息表按指定条件进行批量修改;
  9. 利用快速排序按照图书价格降序排序;
  10. 实现最贵图书的查找;

二、实验分析

数据结构

typedef struct Book{
	char no[8];   //8位书号
	char name[20]; //书名
	double price;     //价格
}Book;
typedef struct LNode {
	Book   data;       //数据域
	struct LNode* next;   //指针域
}LNode;

框架结构

三、代码实现


#include <iostream>
#include <malloc.h> 
using namespace std;
typedef struct book {
	char no[8];   //8位书号
	char name[20]; //书名
	double price;     //价格
}book;
typedef struct lnode {
	book   data;       //数据域
	struct lnode* next;   //指针域
}lnode;
bool iscontain(string str1, string str2) {

	if (str1.find(str2) != string::npos) {
		return true;
	}
	else {
		return false;
	}
}
class linklist {
private:
	lnode* first;
public:
	linklist() {
		first = new lnode;
		first->next = NULL;
	}//无参构造函数,只构建有头指针的空链表
	void insert(book b) {
		lnode* p;
		p = first;
		while (p->next != NULL) {
			p = p->next;
		}
		lnode* s = new lnode;
		s->data = b;
		s->next = p->next;
		p->next = s;
	}

	void print() {
		lnode* p;
		p = first->next;
		while (p != NULL) {
			cout << p->data.no << " " << p->data.name << " " << p->data.price << endl;
			p = p->next;
		}
	}//输出操作

	void insertone() { //新图书插入到图书表指定的位置
		book book;
		int n;
		cout << "请输入插入的位置:";
		cin >> n;
		lnode* p;
		p = first; int count = 0;
		while (p != NULL && count < n - 1) {
			p = p->next;
			count++;
		}
		if (p == NULL) {
			cout << "输入的位置不当,结束本次操作" << endl;
		}
		else {
			cout << "输入图书信息:";
			cin >> book.no >> book.name >> book.price;
			lnode* s = new lnode;
			s->data = book; s->next = p->next; p->next = s;
		}
	}

	void quicksort(lnode* start, lnode* end) { //快速排序按照图书价格降序排序
		// write your code here
		if (start == end)
			return;
		lnode* slow = start;
		lnode* fast = start->next;
		int k = start->data.price;
		while (fast != end) {
			if (fast->data.price > k) {
				book n;
				n = slow->next->data;
				slow->next->data = fast->data;
				fast->data = n;
				slow = slow->next;
			}
			fast = fast->next;
		}
		book n;
		n = slow->data;
		slow->data = start->data;
		start->data = n;
		quicksort(start, slow);
		quicksort(slow->next, end);
	}

	void sort() {
		lnode* begin;
		begin = first->next;
		quicksort(begin, NULL);
	}

	void deletebook() {//删除书
		char n[8];
		cout << "输入要删除的书号:"; cin >> n;
		lnode* p; p = first;
		lnode* q;//记录要删除的书
		while (p->next != NULL) {
			if (p->next->data.no == n) {
				q = p->next;
				p->next = p->next->next;
				delete q;
			}
		}
	}

	int num() {//统计数量
		lnode* p;
		p = first->next;
		int count = 0;
		while (p != NULL) {
			p = p->next;
			count++;
		}
		return count;
	}

	void pricechange() { //图书信息表价格的修改
		lnode* p; p = first->next;
		double sum = 0.00;
		while (p != NULL) {
			sum += p->data.price;
			p = p->next;
		}
		double avg = sum / num();
		lnode* q; q = first->next;
		while (q != NULL) {
			if (q->data.price < avg)
				q->data.price *= 1.2;   //小于平均价格价格上涨20%
			else
				q->data.price *= 1.1;  //大于等于平均价格上涨10%
			q = q->next;
		}
		cout << avg << endl;
		print();
	}

	void searchexp() {  //最贵图书的查找
		lnode* p; p = first->next;
		int count = 0;//记录个数
		double max;//记录最大值
		max = p->data.price;
		while (p != NULL) {
			if (p->data.price == max)count++;
			if (p->data.price > max) {
				max = p->data.price;
				count = 1;
			}
			p = p->next;
		}
		lnode* q; q = first->next;
		while (q != NULL) {
			if (q->data.price == max)cout << q->data.no << " " << q->data.name << " " << q->data.price << endl;
			q = q->next;
		}
	};

	void deleterep() {//图书去重
		lnode* p, * q, * r;
		p = first->next;//p用于遍历链表
		while (p != NULL) {
			q = p;//q遍历p后面的结点,并与p数值比较
			while (q != NULL) {
				if (q->next->data.no == p->data.no) {
					r = q->next;  //r保存需要删掉的结点
					q->next = r->next; //需要删掉的结点的前后结点相连
					delete q;
				}
			}
		}
	}

	void searchfav() { //最爱图书查找
		lnode* p;
		p = first->next;
		char  name[20];
		int n = 0;
		bool tag = 0;
		cout << "请输入最爱图书名字:" << endl;
		cin >> name;
		while (p != NULL) {
			if (iscontain(p->data.name, name)) {
				tag = 1;
				n++;
				cout << p->data.no << " " << p->data.name << " " << p->data.price << endl;
			}
			p = p->next;
		}
		if (tag == 1)
			cout << n << endl;
		else
			cout << "抱歉,没有你的最爱!" << endl;
	}
};

void input(linklist library) { //输出图书信息
	int n;
	cout << "要录入几本图书:"; cin >> n;
	book book;
	for (int i = 0; i < n; i++) {
		cin >> book.no >> book.name >> book.price;
		library.insert(book);
	}
}//录入图书

int main() {
	cout << "                  ***************************************" << endl;
	cout << "                  ***                 图书信息管理            ***" << endl;
	cout << "                  ***************************************" << endl;
	cout << "                  ***                  请选择功能:           ***" << endl;
	cout << "                  ***************************************" << endl;
	cout << "                  ***               1 增加图书信息           ***" << endl;
	cout << "                  ***               2 显示图书信息           ***" << endl;
	cout << "                  ***               3 插入指定图书           ***" << endl;
	cout << "                  ***               4 删除指定图书           ***" << endl;
	cout << "                  ***               5 图书数目统计           ***" << endl;
	cout << "                  ***               6 图书信息去重           ***" << endl;
	cout << "                  ***               7 最爱书籍查找           ***" << endl;
	cout << "                  ***               8 图书信息修改           ***" << endl;
	cout << "                  ***               9 图书价格排序           ***" << endl;
	cout << "                  ***              10 最贵书籍查找           ***" << endl;
	cout << "                  ***               0     退出               ***" << endl;
	cout << "                  ***************************************" << endl;
	linklist library;
	while (true) {
		int order;
		cout << "操作名:";
		cin >> order;
		if (order == 0) {
			break;
		}
		switch (order)
		{
		case 1:
			input(library);
			break;
		case 2:
			library.print();
			break;
		case 3:
			library.insertone();
			break;
		case 4:
			library.deletebook();
			break;
		case 5:
			cout << "书的数目为:" << library.num() << endl;
			break;
		case 6:
			library.deleterep();
			break;
		case 7:
			library.searchfav();
			break;
		case 8:
			library.pricechange();
			break;
		case 9:
			library.sort();
			library.print();
			break;
		case 10:
			library.searchexp();
			break;
		}
		cout << endl;
	}
}

任务二 隐式图的搜索问题

一、实验要求

编写九宫重排问题的启发式搜索(A*算法)求解程序。

在3х3组成的九宫棋盘上,放置数码为1~8的8个棋子,棋盘中留有一个空格,空格周围的棋子可以移动到空格中,从而改变棋盘的布局。根据给定初始布局和目标布局,编程给出一个最优的走法序列。输出每个状态的棋盘
测试数据:初始状态:123456780  目标状态:012345678

【输入格式】
     输入包含三行,每行3各整数,分别为0-8这九个数字,以空格符号隔开,标识问题的初始状态。0表示空格,例如:
                               2     0     3

                               1     8     4

                               7     6     5

二、实验分析

数据结构

struct node {
    int nine[N][N];//数码状态
    int f;//估价值
    int g;//用于记录当前为第几层
    string direct = "";//空格移动方向
    struct node* parent;//父节点
};
struct Node {
    node data;
    struct Node* next;
};
class LinkList {
public:
    LinkList() {
        Node p;
        first = new Node;
        first->next = NULL;
    }//无参构造函数,只构建有头指针的空链表

Open和close采用单链表结构;

算法设计

       启发式搜索算法定义了一个估价函数 f(n),与问题相关的启发式信息都被计算为一定的 f(n) 的值,引入到搜索过程中。f(n)=g(n)+h(n),其中f(n) 是节点n的估价函数,g(n)是在状态空间中从初始节点到节点n的实际代价,h(n)是从节点n到目标节点最佳路径的估计代价。 在本次实验中,g(n)是从初始状态变换到当前状态所移动的步数,估计函数h(n)估计的是节点n到目标节点的距离,我们是用现状态与目标状态中数字的错位数来估量的。举例如下:


————————————————
根据以上规则设计的启发式搜索算法AStar(open, close,mubiao)

三、代码实现

#include <iostream>
#include<ctime>//计时函数
using namespace std;
const int N = 3;
struct node {
    int nine[N][N];//数码状态
    int f;//估价值
    int g;//用于记录当前为第几层
    string direct = "";//空格移动方向
    struct node* parent;//父节点
};
struct Node {
    node data;
    struct Node* next;
};
int h(int now[N][N], int order[N][N]) {
    int h0 = 0;
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            if (now[i][j] != order[i][j])
                h0++;
    return h0;
}//用于计算和目标状态还有多少位不对应
int equal1(int now[N][N], int order[N][N]) {//判断两个数组是否相等
    int h0 = 0;
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            if (now[i][j] != order[i][j]) {
                h0 = 1;
                break;
            }
    return h0;//返回0时,全部相等;为1时,不相等
}
int* find0(int now[N][N]) {
    static int zuobiao[2] = { 0,0 };
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            if (now[i][j] == 0)
            {
                zuobiao[0] = i; zuobiao[1] = j;
                return zuobiao;
            }
}//找到0的坐标
class LinkList {
public:
    LinkList() {
        Node p;
        first = new Node;
        first->next = NULL;
    }//无参构造函数,只构建有头指针的空链表
    int length() {
        Node* p;
        p = first->next;
        int count = 0;
        while (p != NULL) {
            p = p->next;
            count++;
        }
        return count;
    }//求链表长度
    void insert(node x) {
        Node* p;
        p = first;
        while (p->next != NULL) {
            p = p->next;
        }
        Node* s = new Node;
        s->data = x;
        s->next = p->next;
        p->next = s;
    }//插入操作(尾插法)
    node pop() {
        Node* d;
        d = first->next;
        first->next = first->next->next;
        return d->data;
    }//取第一个点
    int travel(node x) {
        int s = 0;
        Node* p;
        p = first->next;
        while (p != NULL) {
            if (equal1(p->data.nine, x.nine) == 0) {
                s = 1;
                break;
            }
            p = p->next;
        }
        return s;
    }//用于遍历close表,判断是否可以扩展,即判断close中是否有x,有则返回1(不可拓展),无返回0(可拓展)
    void sortlist() {
        Node* pre, * cur, * next, * end;//pre前一项 cur当前项 next后一项 end控制循环次数(优化冒泡)
        end = NULL;
        while (first->next != end) {
            bool isSorted = true;
            for (pre = first, cur = pre->next, next = cur->next; next != end; pre = pre->next, cur = cur->next, next = next->next)
                //初始化三个指针 ; 判断是否到达结束位置 ; 三个指针集体后移
            {
                if (cur->data.f > next->data.f) //从小到大
                {
                    pre->next = next;
                    cur->next = next->next;
                    next->next = cur;
                    Node* temp = cur; cur = next; next = temp;//此时next变前一项,cur变后一项  交换next cur
                    isSorted = false;
                }
            }
            end = cur;//一轮循环结束 最后一项已经排好 end提前一项 (冒泡原理)
            if (isSorted) {
                break;
            }
        }
    }//按从小到大的顺序重新进行排序
private:
    Node* first;
};
void print(node s) {
    if (s.direct != "") {
        print(*s.parent);
        cout << "**********" << endl;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++)
                cout << s.nine[i][j] << " ";
            cout << endl;
        }
    }
    else
        return;
}//递归输出s的父节点所指向的图
void AStar(LinkList open, LinkList close, int mubiao[N][N]) {
    if (open.length() == 0) {
        cout << "无解";
    }//如果Open表为空,则问题无解,失败退出
    else {
        node s = open.pop(); close.insert(s);//把Open表的第一个节点取出放入Closed表,并记该节点为s;
        s.g++;
        if (equal1(s.nine, mubiao) == 0) {
            cout << "找到了问题的解,操作为:" << endl;//考察节点s是否为目标节点。若是,则找到了问题的解,成功退出;
            cout << s.direct << endl;//输出操作
            print(s);//打印每一次图的变化
        }
        else {
            int x, y;
            x = find0(s.nine)[0]; y = find0(s.nine)[1];//0所在的坐标
            if (y != 0) {
                node nleft;//向左操作
                nleft = s;
                int index = nleft.nine[x][y - 1];
                nleft.nine[x][y - 1] = 0;
                nleft.nine[x][y] = index;
                if (close.travel(nleft) == 0 && open.travel(nleft) == 0) {//看操作后的图是否已经存在过
                    nleft.direct = s.direct + "L";
                    nleft.parent = &s;
                    nleft.f = nleft.g + h(nleft.nine, mubiao);
                    open.insert(nleft);
                }
            }
            if (y != N - 1) {
                node nright;//向右操作
                nright = s;
                int index = nright.nine[x][y + 1];
                nright.nine[x][y + 1] = 0;
                nright.nine[x][y] = index;
                if (close.travel(nright) == 0 && open.travel(nright) == 0) {//看操作后的图是否已经存在过
                    nright.direct = s.direct + "R";
                    nright.parent = &s;
                    nright.f = nright.g + h(nright.nine, mubiao);
                    open.insert(nright);
                }
            }
            if (x != 0) {//向上操作
                node nup;
                nup = s;
                int index = nup.nine[x - 1][y];
                nup.nine[x - 1][y] = 0;
                nup.nine[x][y] = index;
                if (close.travel(nup) == 0 && open.travel(nup) == 0) {//看操作后的图是否已经存在过
                    nup.direct = s.direct + "U";
                    nup.parent = &s;
                    nup.f = nup.g + h(nup.nine, mubiao);
                    open.insert(nup);
                }
            }
            if (x != N - 1) {//向下操作
                node ndown;
                ndown = s;
                int index = ndown.nine[x + 1][y];
                ndown.nine[x + 1][y] = 0;
                ndown.nine[x][y] = index;
                if (close.travel(ndown) == 0 && open.travel(ndown) == 0) {//看操作后的图是否已经存在过
                    ndown.direct = s.direct + "D";
                    ndown.parent = &s;
                    ndown.f = ndown.g + h(ndown.nine, mubiao);
                    open.insert(ndown);
                }
            }
            open.sortlist();//对open表进行冒泡排序,索引为f值
            AStar(open, close, mubiao);//递归搜索
        }
    }
}
void input(int arr[N][N]) {
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            cin >> arr[i][j];
}//输入数组,用于构造数组
int main() {
    node pNode;
    pNode.g = 0;
    cout << "输入原始图" << endl;
    input(pNode.nine);
    cout << endl << "输入目标图" << endl;
    int mubiao[N][N];
    input(mubiao);
    LinkList open, close;//构建open,close表
    pNode.f = h(pNode.nine, mubiao) + pNode.g;//f(S0)=g(S0)+h(S0)
    open.insert(pNode);//把初始节点S0 放入Open表中
    clock_t start, finish;
    start = clock();
    AStar(open, close, mubiao);
    finish = clock();
    int time = finish - start;
    cout << "运行的时间为" << time << "毫秒" << endl;
}

任务三 基于二叉排序树的低频词过滤系统

一、实验要求

  1. 对于一篇给定的英文文章,利用线性表和二叉排序树来实现单词频率的统计,实现低频词的过滤,并比较两种方法的效率。具体要求如下:
  2. 读取英文文章文件(Infile.txt),识别其中的单词。
  3. 分别利用线性表和二叉排序树构建单词的存储结构。当识别出一个单词后,若线性表或者二叉排序树中没有该单词,则在适当的位置上添加该单词;若该单词已经被识别,则增加其出现的频率。
  4. 统计结束后,删除出现频率低于五次的单词,并显示该单词和其出现频率。
  5. 其余单词及其出现频率按照从高到低的次序输出到文件中(Outfile.txt),同时输出用两种方法完成该工作所用的时间。
  6. 计算查找表的ASL值,分析比较两种方法的效率。
  7. 系统运行后主菜单如下:

当选择1后进入以下界面:

 

其中选择2时显示利用线性表来实现所有功能所用的时间。

当在主菜单选择2二叉排序树后,进入的界面与上图类同。

二、实验分析

数据结构

typedef struct 
{
	char word[20];
	int count;
}danci;

//线性表的存储表示
typedef struct
{
	danci *a;
	int length;
}SqList;

//二叉排序树的存储表示
typedef struct BSTNode{
   danci b;		    //单词出现频率
   struct BSTNode *lchild,*rchild;
} BSTNode, *BSTree;

流程及算法设计

三、代码实现

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<stdio.h>
#include<string.h>//字符串比对
#include<string>
#include<fstream>//导入导出
#include<vector>
#include<ctime>//计时函数
#include <iomanip>
using namespace std;
#define MAXSIZE 1000

typedef struct
{
	char word[20];
	int count;
}danci;
//线性表的存储表示
typedef struct
{
	danci* a;
	int length;
}SqList;
//线性表的初始化
void InitList(SqList& L)
{
	L.a = new danci[MAXSIZE];
	if (!L.a)
		cout << "存储空间分配失败!" << endl;
	else
		L.length = 0;
}

//比对重复计数
void jishu(SqList& L, danci e)
{
	int i;
	for (i = 1; i <= L.length; i++)
	{
		if (strcmp(L.a[i].word, e.word) == 0)
		{
			L.a[i].count++;
			break;
		}
	}
	if (L.length == 0 || i == L.length + 1)
	{
		L.length++;
		int j = L.length;
		L.a[j] = e;
	}
}

//输入数据
void CreateList_text(SqList& L) {
	int K;
	FILE* fp;
	char ch;
	danci e;
	fp = fopen("InFile.txt", "r");
	while (!feof(fp))
	{
		ch = getc(fp);//获取当前字符
		if (ch == ' ' || ch == 10 || ch == 44 || ch == 46 || ch == '。')
		{//ASCLL码中10为换行符  chr(10) 换行
			continue;
		}
		if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))//发现一个单词
		{
			K = 0;
			e.count = 1;
			while ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == 39) || ch == '-')  //Char("39")对应标点 ’
			{
				if (ch >= 'A' && ch <= 'Z')
				{
					ch += 32;//转换成小写
				}
				e.word[K++] = ch;//把当前字母存入数组
				ch = getc(fp);
			}
			e.word[K++] = '\0';//结束标志\0
		}
		jishu(L, e);
	}
}
//显示函数
void display(SqList& L)
{
	int i;
	cout << "出现次数大于五次的单词" << endl;
	cout << "单词" << setw(15) << "数量" << setw(15) << endl;
	for (i = 1; i <= L.length; i++)
	{
		cout << L.a[i].word << setw(15) << L.a[i].count << setw(15) << endl;
	}
}
//判断出现次数小于5
void count_five(SqList& L)
{
	int i, n = 1;
	cout << "出现次数小于五次的单词" << endl;
	cout << setw(15) << setw(15) << endl;
	for (i = L.length; i > 0; i--)
	{
		if (L.a[i].count < 5)
		{
			cout << L.a[i].word << setw(15) << L.a[i].count << setw(15) << endl;
			for (int j = i; j <= L.length - 1; j++)
			{
				L.a[j] = L.a[j + 1];
			}
			--L.length;
		}

	}

}
//根据count排序
void sort(SqList& L)
{
	int i, j;
	for (i = 2; i <= L.length; ++i)
		if (L.a[i].count > L.a[i - 1].count)
		{
			L.a[0] = L.a[i];
			L.a[i] = L.a[i - 1];
			for (j = i - 2; L.a[0].count > L.a[j].count; --j)
				L.a[j + 1] = L.a[j];
			L.a[j + 1] = L.a[0];
		}
}
//输出到文件
void output(SqList& L)
{
	ofstream outfile;
	outfile.open("OutFile.txt");
	outfile << "出现次数大于5的单词:\n";
	outfile << "单词" << '\t' << "次数" << endl;
	for (int i = 1; i <= L.length; i++)
	{
		outfile << L.a[i].word << '\t' << L.a[i].count << endl;
	}
	outfile.close();
}
计算ASL
void ASLlist(SqList& L)
{
	ofstream outfile;
	int n = int(L.length);
	double asl = 1.00 * (n - 1) / 2;//((n-1)*n/2)/n
	cout << asl << endl;
}


//二叉排序树的存储表示
typedef struct BSTNode {
	danci b;		    //单词出现频率
	struct BSTNode* lchild, * rchild;
} BSTNode, * BSTree;
void InsertBST(BSTree& T, danci e)
{
	if (!T)
	{
		BSTree S = (BSTree)malloc(sizeof(BSTNode));
		S->b = e;
		S->lchild = S->rchild = NULL;
		T = S;
	}
	else if (strcmp(e.word, T->b.word) < 0)
	{
		InsertBST(T->lchild, e);
	}
	else if (strcmp(e.word, T->b.word) > 0)
	{
		InsertBST(T->rchild, e);
	}
	else if (strcmp(e.word, T->b.word) == 0)
	{
		T->b.count++;
	}
}
//获取单词
void getdanci(BSTree& T)
{
	int K;
	FILE* fp;
	char ch;
	danci e;
	fp = fopen("InFile.txt", "r");
	while (!feof(fp))
	{
		ch = getc(fp);//获取当前字符
		if (ch == ' ' || ch == 10 || ch == 44 || ch == 46 || ch == '。')
		{//ASCLL码中10为换行符
			continue;
		}
		if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))//发现一个单词
		{
			K = 0;
			e.count = 1;
			while ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == 39 || ch == '-')
			{
				if (ch >= 'A' && ch <= 'Z')
				{
					ch += 32;//转换成小写
				}
				e.word[K++] = ch;//把当前字母存入数组
				ch = getc(fp);
			}
			e.word[K++] = '\0';//结束标志\0
		}
		InsertBST(T, e);
	}
}

//计算ASL
int num[MAXSIZE];//用来记录每层多少个结点,第一层num[0],第二层num[1]....
void MidBSTASL(BSTree& T, int deep)
{
	if (T != NULL)
	{
		num[deep]++;
		deep++;
		MidBSTASL(T->lchild, deep);
		MidBSTASL(T->rchild, deep);
	}
}
void ASL(BSTree& T) {
	int deep = 0;
	MidBSTASL(T, deep);
	int i = 0;
	int sum = 0;//记录ASL的分子
	int sumnod = 0;//记录二叉树里结点的总数
	while (num[i] != 0) {
		i += 1;
		sum += i * num[i - 1];
		sumnod += num[i - 1];
	}
	double asl;
	if (sumnod != 0)
		asl = 1.00 * sum / sumnod;
	else
		asl = 0;
	cout << asl << endl;
}

//输出显示二叉树(中序遍历)
void MidBST(BSTree& T)
{
	if (T != NULL)
	{
		MidBST(T->lchild);
		cout << T->b.word << setw(15) << T->b.count << setw(15) << endl;
		MidBST(T->rchild);
	}
}
void Insert(BSTree& S, danci e)
{
	if (!S)
	{
		BSTree W = (BSTree)malloc(sizeof(BSTNode));
		W->b = e;
		W->lchild = NULL; W->rchild = NULL;
		S = W;
	}
	else if (e.count >= S->b.count)
	{
		Insert(S->lchild, e);
	}
	else if (e.count < S->b.count)
	{
		Insert(S->rchild, e);
	}
}
//二叉排序树的删除
void SerachBST(BSTree& T, BSTree& S)
{
	if (T)
	{
		SerachBST(T->lchild, S);
		if (T->b.count >= 5)
		{
			danci e;
			e = T->b;
			Insert(S, e);
		}
		if (T->b.count < 5)
		{

			cout << T->b.word << setw(15) << T->b.count << setw(15) << endl;
		}
		SerachBST(T->rchild, S);
	}
}
void SerachBST5(BSTree& T, BSTree& S)
{
	if (T)
	{
		SerachBST(T->lchild, S);
		if (T->b.count >= 5)
		{
			danci e;
			e = T->b;
			Insert(S, e);
		}
		SerachBST(T->rchild, S);
	}
}
void sorttree() {

}
void shuchu(BSTree& S)
{
	if (S != NULL)
	{
		shuchu(S->lchild);
		ofstream outfile;
		outfile.open("OutFile.txt", ios::app);
		outfile << S->b.word << '\t' << S->b.count << endl;
		outfile.close();
		shuchu(S->rchild);
	}
}
void menu()
{
	cout << "1、线性表" << endl;
	cout << endl;
	cout << "2、二叉排序树" << endl;
	cout << endl;
	cout << "3、退出系统" << endl;
	cout << endl;
}

void menu1() {
	cout << "1、连续执行至完毕" << endl;
	cout << endl;
	cout << "2、显示执行时间" << endl;
	cout << endl;
	cout << "3、单步执行:识别并统计单词" << endl;
	cout << endl;
	cout << "4、单步执行:删除并显示出现频率低的单词" << endl;
	cout << endl;
	cout << "5、单步执行:输出其余单词及其频率" << endl;
	cout << endl;
	cout << "6、单步执行:计算并输出ASL值" << endl;
	cout << endl;
	cout << "7、返回主菜单" << endl;
	cout << endl;
}
int main()
{
	while (1)
	{
		menu();
		string key;
		cout << "请选择需要执行的操作:";
		cin >> key;
		system("pause");
		system("cls");
		if (key != "1" && key != "2" && key != "3")
		{
			cout << "输入的操作不存在,请重新输入!" << endl;
		}
		if (key == "1")
		{
			int time = 0;
			SqList L;
			while (1)
			{
				menu1();
				string n;
				cout << "请选择需要执行的操作:";
				cin >> n;
				if (n == "1")
				{
					clock_t start, finish;
					start = clock();
					InitList(L);
					CreateList_text(L);
					sort(L);
					count_five(L);
					display(L);
					output(L);
					ASLlist(L);
					cout << "已输出到文件夹!" << endl;
					finish = clock();
					time = finish - start;
					cout << "运行的时间为" << time << "毫秒" << endl;
				}
				if (n == "2") {
					cout << "运行的时间为" << time << "毫秒" << endl;
				}
				if (n == "3")
				{
					InitList(L);
					CreateList_text(L);
					cout << "已统计完成!" << endl;
				}
				if (n == "4")
				{
					count_five(L);
				}
				if (n == "5")
				{
					sort(L);
					display(L);
					output(L);
					cout << "已输出到文件夹!" << endl;
				}
				if (n == "6")
				{
					cout << "单步执行:计算并输出ASL值" << endl;
					int asl;
					ASLlist(L);
				}
				if (n == "7") { system("cls"); break; }
				system("pause");
				system("cls");
			}
		}
		if (key == "2")
		{
			int time = 0;
			BSTree T, S;
			T = NULL;
			S = NULL;
			while (1)
			{
				menu1();
				string n;
				cout << "请选择需要执行的操作:";
				cin >> n;
				if (n == "1")
				{
					clock_t start, finish;				
					start = clock();
					T = NULL;
					S = NULL;
					getdanci(T);
					cout << "出现次数小于5的单词:" << endl;
					cout << setw(15) << setw(15) << endl;
					SerachBST(T, S);
					cout << "出现次数大于5的单词:" << endl;
					cout << setw(15) << setw(15) << endl;
					MidBST(S);
					ofstream outfile;
					outfile.open("OutFile.txt");
					outfile << "出现次数大于5的单词:" << endl;
					outfile << "单词" << '\t' << "次数" << endl;
					outfile.close();
					shuchu(S);
					cout << "单步执行:计算并输出ASL值" << endl;
					ASL(S);
					finish = clock();
					time = finish - start;
					cout << "运行的时间为" << time << "毫秒" << endl;
				}
				if (n == "2")
				{
					cout << "运行的时间为" << time << "毫秒" << endl;

				}
				if (n == "3")
				{
					S = NULL;
					getdanci(T);
					cout << "已统计完成!" << endl;
				}
				if (n == "4")
				{
					cout << "出现次数小于5的单词:" << endl;
					cout << setw(15) << setw(15) << endl;
					SerachBST(T, S);
				}
				if (n == "5")
				{
					if (S==NULL)
						SerachBST5(T, S);
					cout << "其余单词及其频率:" << endl;
					cout << setw(15) << setw(15) << endl;
					MidBST(S);
					ofstream outfile;
					outfile.open("OutFile.txt");
					outfile << "其余单词及其频率:" << endl;
					outfile << "单词" << '\t' << "次数" << endl;
					outfile.close();
					shuchu(S);
					cout << "已输出到文件!" << endl;

				}
				if (n == "6")
				{
					cout << "单步执行:计算并输出ASL值" << endl;
					ASL(S);
				}
				if (n == "7") { system("cls"); break; }
				system("pause");
				system("cls");
			}
		}
		if (key == "3")
		{
			break;
		}
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值