进一步熟悉VC++开发环境,熟悉用C++完成一个应用程序的设计过程,掌握有关编辑、调试和整合程序的方法和技巧。
通过此设计,了解《算法与数据结构》课程的知识结构;熟悉各算法的实现与使用;体会数据结构在问题求解中的重要性以及抽象数据类型的优越性。
通过此设计,进一步认识面向对象编程的实质与实用性。学会面向对象编程范式,进一步掌握民向对象编程的方法。
根据《算法与数据结构》课程的结构体系,设计一个基于DOS菜单的应用程序。要利用多级菜单实现各种功能。比如,主界面是大项,诸如线性表、栈与队列、串与数组及广义表等,子菜单使这些大项中的一些功能或者小项。要求所有子菜单退出到他的父菜单。
编程实现时,要用到C++的面向对象的功能。
为了在程序中体现出教材的章节体系,考虑到教材的章节体系原本的结构,将教材的书目章节体系使用树状图表现出来。
使用MFC,MFC本身的框架中就已经体现了这一思想,同时将自己写的算法封装成为一个能够执行一定功能的类。
这次主要实现书中的排序算法和图的算法。对于排序的算法,提供算法间的相互比较和结果统计展示。同时在程序中设置使用OpenMP对程序加速。
该类的作用是呈现主要程序内容,提供对目录视图发出的消息的处理。
该类的功能是产生树形目录,并且提供对于用户输入的响应。在类间自定义并且传递了消息来完成所需要的功能。
在这个类中使用多线程实现了排序算法的比较和结果分析。
在程序产生50000样本数据时,通过OpenMP使得其可以并行化执行,同时在处理样本数据的时候,通过将10个计时任务分割成4组任务,然后并行化运行,获得了更好的程序性能,同时降低了测试时间,同时也减小了测试的误差,使得排序算法的区分度更加明显。同时对于算法运行时间的的计算部分中,循环的各分量间没有相关性,这很好的保证了并行化的正确性。无论启用OpenMP与否,在窗口的数据处理和准备过程都是启用OpenMP的。
在程序的排序算法比较窗口上,界面的绘制需要数据运算的支持,如果在程序的主线程中进行运算会阻塞程序的执行,造成程序无法响应,为了解决这个问题,在另一个线程中进行大量数据的计算任务,同时为了避免程序在准备运算结果的时候用户点击绘图按钮导致异常,在进行数据计算的时候会有进度条进行提示并且会禁用按钮。
这个类实现了9中排序算法,实现了直接插入排序,折半查找排序,2路查找排序,希尔排序,冒泡排序,快速排序,简单选择排序,堆排序,归并排序。其中为了显示算法的比较性,同时实现了一个调用C语言函数库中提供的排序算法的接口。该类可以实现大量数据的排序,排序算法都经过了检验,都是可以工作的。并且算法中都通过使用了OpenMP。
#defineSWAP(X,Y)int tmp=X;X=Y;Y=tmp;
#defineLT(X,Y) X
classSortCollection
{
private:
void heap(int*src,int n);
void headAdjust(int a[],int i,int m);
void mergeProcess(int a[],int p,int r);
void merge(int *num,int start,int middle,int end);
int partion(int *Src,int low,int high);
void QSort(int *Src,int low,int high);
public:
SortCollection();
~SortCollection();
int* directSort(int* src,int n); //直接插入排序法
int* BInsertSort(int* Src,int n); //折半插入排序法
int* twowaySort(int* Src,int n); //二路插入排序法
int* shellSort(int* Src,int n); //希尔插入排序法
int* quickSort(int* Src,int n); //快速排序法
int* simchoSort(int* Src,int n); //简单选择排序法
int* heapSort(int* Src,int n);//堆排序法
int* mergeSort(int* Src,int n); //归并排序法
int* stdSort(int* Src,int n); //标准库排序
int* bubble(int* src,int n); //冒泡排序法
};
排序法的入口参数都是要排序的数组,以及数组的大小。返回值是排序后的数组,没有更改输入的数组。在程序内部,为了优化性能,使用了内存复制而不是循环赋值。
这是自己实现的一个提供高精度计时的类,可以提供已CPU循环数为单位的时间记录。
classcycleTimer
{
public:
cycleTimer()
{
}
~cycleTimer()
{
}
void start()
{
m_start = GetCpuCycle();
}
unsigned__int64 end()
{
m_end = GetCpuCycle();
return m_end;
}
unsigned__int64 getLastTime()
{
m_end = GetCpuCycle();
return m_end - m_start;
}
private:
unsigned__int64 m_start;
unsigned__int64 m_end;
inline unsigned__int64 GetCpuCycle()
{
__asm _emit 0x0F
__asm _emit 0x31
}
};
该类排序算法集合类的使用了OpenMp的版本。
#defineSWAP(X,Y)int tmp=X;X=Y;Y=tmp;
#defineLT(X,Y) X
classSortCollection
{
private:
void heap(int*src,int n);
void headAdjust(int a[],int i,int m);
void mergeProcess(int a[],int p,int r);
void merge(int *num,int start,int middle,int end);
int partion(int *Src,int low,int high);
void QSort(int *Src,int low,int high);
public:
SortCollection();
~SortCollection();
int* directSort(int* src,int n); //直接插入排序法
int* BInsertSort(int* Src,int n); //折半插入排序法
int* twowaySort(int* Src,int n); //二路插入排序法
int* shellSort(int* Src,int n); //希尔插入排序法
int* quickSort(int* Src,int n); //快速排序法
int* simchoSort(int* Src,int n); //简单选择排序法
int* heapSort(int* Src,int n);//堆排序法
int* mergeSort(int* Src,int n); //归并排序法
int* stdSort(int* Src,int n); //标准库排序
int* bubble(int* src,int n); //冒泡排序法
};
排序法的入口参数都是要排序的数组,以及数组的大小。返回值是排序后的数组,没有更改输入的数组。在程序内部,为了优化性能,使用了内存复制而不是循环赋值。使用了排序算法中部分使用了OpenMP,在适合并行化并且并行化不会造成结果错误的地方使用了OpenMP。
纵坐标表示算法运行所使用的时间。
纵坐标表示算法运行所使用的时间。
课程设计其实使用控制台程序就已经完全可以体现出算法和数据结构的精髓,但是现在控制台程序并不常用,如果想做出以前没有做出过的东西来,就需要尝试,需要新的设计,需要新的想法。
在和老师交流后,对题目的理解是着重完成某个章节的内容,但是书目整体要体现出来,并且要对面向对象的思想有所体会,在课设开始的前一周,我已经用C#实现了一个控制台版的程序,整书完整的实现了四章内容,并且接口编程,算法大多是使用了泛型编程的,但是我发现控制台界面无法输入出了数字和字符串以外的东西,也就是说算法写出来基本上是没有用处的。于是这次的课程设计使用MFC,弱化算法,用图像来表现出算法的运行效果。
这次的课程设计,实现了书目的章节体系的同时主要着力于实现排序的算法和结果的比较,同时体会到了数据结构在计算机中的应用,许多数据的处理都需要数据结构,
这次的课程设计主要应用了一些新的知识,MFC以及多线程程序,还有OpenMP技术的应用为以后的编程打开了新的窗口,这次的课程设计会成为新的起点。