基于插入排序方法的类模板设计与实现.docx

上传人:b****4 文档编号:5122109 上传时间:2022-12-13 格式:DOCX 页数:22 大小:340.50KB
下载 相关 举报
基于插入排序方法的类模板设计与实现.docx_第1页
第1页 / 共22页
基于插入排序方法的类模板设计与实现.docx_第2页
第2页 / 共22页
基于插入排序方法的类模板设计与实现.docx_第3页
第3页 / 共22页
基于插入排序方法的类模板设计与实现.docx_第4页
第4页 / 共22页
基于插入排序方法的类模板设计与实现.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

基于插入排序方法的类模板设计与实现.docx

《基于插入排序方法的类模板设计与实现.docx》由会员分享,可在线阅读,更多相关《基于插入排序方法的类模板设计与实现.docx(22页珍藏版)》请在冰豆网上搜索。

基于插入排序方法的类模板设计与实现.docx

基于插入排序方法的类模板设计与实现

成绩评定表

学生姓名

郝晓鹏

班级学号

1103060129

专业

通信工程

课程设计题目

基于插入排序方法的类模板设计与实现

 

 

组长签字:

成绩

 

日期

20年月日

课程设计任务书

学院

信息科学与工程

专业

通信工程

学生姓名

郝晓鹏

班级学号

1103060129

课程设计题目

基于插入排序方法的类模板设计与实现

实践教学要求与任务

建立一维数组数据结构的模板类,使一维数组中的数据元素可以是char,int,float等多种数据类型,并对数组元素实现插入类排序。

主要完成如下功能:

(1)实现数组数据的输入和输出;

(2)实现直接插入排序功能;

(3)实现2-路插入排序功能;

(4)实现希尔排序功能;

(5)将每种排序功能作为类的成员函数实现,编写主函数测试上述排序功能。

工作计划与进度安排

第17周:

分析题目,查阅课题相关资料,进行类设计、算法设计;

第18周:

程序的设计、调试与实现;

第19周:

程序测试与分析,撰写课程设计报告,进行答辩验收。

指导教师:

201年月日

专业负责人:

201年月日

学院教学副院长:

201年月日

摘要

排序是计算机程序设计中的一种重要运算,它的功能是将一个数据元素(或记录)的任意序列重新排列成一个按关键字有序的序列。

简言之,所谓排序就是根据关键字值的非递减或非递增次序,把文件中的各记录依次排列起来,可使一个无序文件变成有序文件的一种操作。

有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法。

插入排序包括:

直接插入排序,折半插入排序,2-路插入排序,表插入排序,希尔排序。

关键词:

直接插入排序法;2—路插入排序法;希尔排序法;MFC工程

1需求分析

(1)有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法。

插入排序包括:

直接插入排序,折半插入排序,2-路插入排序,表插入排序,希尔排序。

(2)插入排序的基本思想是:

在一个已排好序的记录子集的基础上,每一步将下一个待排序的记录有序地插入到已排好序的记录子集中,知道将所有待排记录全部插入为止。

这很像打扑克牌时,没抓一张牌,插入到合适位置,知道抓完牌为止,即可得到一个有序序列。

(3)直接插入排序:

将一个记录插入到已排序好的有序表中,从而得到一个新的、记录数增1的有序表。

设整个排序有n个数,则进行n-1趟插入,即:

先将序列中的第1个记录看成是一个有序的子序列,然后从第2个记录起逐个进行插入,直至整个序列变成按关键字非递减有序列为止。

(4)2-路插入排序是在折半插入排序的基础上的发展。

其目的是减少排序过程中记录移动的次数,但为此需n个记录的辅助空间。

具体做法是:

另设一个和L.r同类型的数组d,首先将L.r[1]赋值给d[1],将d[1]看成是排好序的序列中处于中间位置的记录,然后从L.r中第2个记录起依次插入到d[1]之前或之后的有序序列中。

先将待排序记录的关键字和d[1]的关键字比较,若L.r[i].key

反之,将L.r[i]插入到d[1]之后的有序表中。

在实现算法时,将d看成一个循环向量,并设两个指针first和final分别指示排序过程中得到的有序序列中的第一个记录和最后一个记录在d中的位置。

(5)希尔排序又称“缩小增量排序”,它属于插入排序类。

它的基本思想是:

先将整个待排序的记录分割成若干子序列分别进行“直接插入排序”,待整个序列中的记录”基本有序“时,再对全体记录进行一次直接插入排序。

 

2算法基本原理

(1)直接插入排序算法:

排序过程为:

将一个记录插入到已排序好的有序表中,从而得到一个新的、记录数增1的有序表。

设整个排序有n个数,则进行n-1趟插入,即:

先将序列中的第1个记录看成是一个有序的子序列,然后从第2个记录起逐个进行插入,直至整个序列变成按关键字非递减有序列为止。

直接插入排序过程如图2.1所示:

 

(2)2-路插入排序算法:

排序过程为:

另设一个和L.r同类型的数组d,首先将L.r[1]赋值给d[1],将d[1]看成是排好序的序列中处于中间位置的记录,然后从L.r中第2个记录起依次插入到d[1]之前或之后的有序序列中。

先将待排序记录的关键字和d[1]的关键字比较,若L.r[i].key

反之,将L.r[i]插入到d[1]之后的有序表中。

在实现算法时,将d看成一个循环向量,并设两个指针first和final分别指示排序过程中得到的有序序列中的第一个记录和最后一个记录在d中的位置。

2-路插入排序过程如图2.2所示:

 

(3)希尔排序算法:

(3)希尔排序算法:

(3)希尔排序算法:

基本思想是:

先将整个待排序的记录分割成若干子序列分别进行“直接插入排序”,待整个序列中的记录”基本有序“时,再对全体记录进行一次直接插入排序。

希尔排序过程如下图2.3:

初始关键字:

49386597761327495504

 

13274955044938659776

 

图2.3希尔排序过程图

3类设计

从上面的过程分析可以看到,本设计的关键所在是对所输入数据分别进行三种不同的排序,所输入的数据有两种类型,分别为int型和char型。

对于两种不同的数据类型,可以先建立一个类模板,虚拟类型名为Type型,类模板名为Sort。

在主函数main()中建立两个对象,分别制定对象类型为int型和char型。

在虚拟类中声明各成员函数:

voidwrite()读入数组函数;voidInsertionSort()直接插入排序函数;voidSrsort(Typemi[])二路排序;voidShellSort(Typeda[],intk)voidShellinsert(Typedk)希尔排序。

Voidprint()输出排序结果函数。

分别在类模板外声明各成员函数。

4基于控制台的应用程序

整个程序三部分。

首先是声明类模板,其中包括输入输出数据成员函数的声明以及直接插入排序,2—路排序,希尔排序的成员函数声明。

其次是在类外对所有成员函数进行定义。

最后在主函数中实现数据的排序操作。

4.1类的接口设计

#include

#include

#include

#include

#definenum50

template//声明一个模板,虚拟类型名为Type

classSort//类模板名为Sort

{private:

intlen;

public:

voidwrite();//声明读入数组函数

voidInsertionSort();//声明直接插入排序函数

voidSrsort(Typemi[]);//声明2-路插入排序函数

voidShellSort(Typeda[],intt);

voidShellinsert(Typedk);//声明希尔排序函数

voidprint();//声明输出结果函数

Typearray[num];

};

Template的意思是“模板”,是声明类模板时必须写的关键字。

在template后面的尖括号内的内容为累的参数列表,关键字class表示其后面的是类型参数。

在本程序中Type就是一个类型参数名,它只是一个虚拟类型参数名,在之后的主函数中将被实际的类型名取代。

4.2类的实现

template//直接插入排序

voidSort:

:

InsertionSort()

{inti,j;

for(i=2;i<=len;++i)

if(array[i]

{array[0]=array[i];

for(j=i-1;array[0]

array[j+1]=array[j];

array[j+1]=array[0];

}

}

template//2-路插入排序

voidSort:

:

Srsort(Typemi[])

{inti,j;

Typem,first,final,low,high;

Typed[100];

d[1]=array[1];

first=1;final=1;m=1;

for(i=2;i<=len;++i)

{

m=(first+final)/2;

if(array[i]

{

low=first;high=m-1;

}

else

{

low=m;high=final;

}

while(low<=high)//查找插入位置

{m=(low+high)/2;

if(array[i]

high=m-1;

else

low=m+1;}

if(array[i]>d[m])m++;

for(j=final+1;j>m;j--)

d[j]=d[j-1];

d[m]=array[i];

final++;

}

j=first;

for(i=1;i<=len;++i)

{

array[i]=d[j];++j;

}

}

template//希尔排序

voidSort:

:

Shellinsert(Typedk)

{inti,j;

for(i=dk+1;i<=len;++i)

if(array[i]

{array[0]=array[i];

for(j=i-dk;j>0&&(array[0]

array[j+dk]=array[j];

array[j+dk]=array[0];

}

}

template

voidSort:

:

ShellSort(Typeda[],intt)

{

intk;

k=len/2;

while(k)

{Shellinsert(k);

k=k==2?

1:

k/2;

}

}

template//读入数组

voidSort:

:

write()

{inti,l;printf("请输入数组长度:

");

scanf("%d",&l);

len=l;

printf("请输入数组元素:

\n");

for(i=1;i<=l;i++)

cin>>array[i];

}

template//显示结果

voidSort:

:

print()

{inti;

printf("排序后的数组为:

\n");

for(i=1;i<=len;i++)

cout<

cout<

}

在类模板外定义成员函数时,应写成类模板形式。

不论成员函数在类内定义还是在类外定义,成员函数的代码段都用同一种方式储存,即都不占用对象的存储空间。

一个对象所占的空间大小只取决于该对象中数据成员所占的空间,而与成员函数无关。

函数代码是存储在对象空间之外的。

4.3主函数设计

voidmain()

{inti,j;

Sorts;

Sortp;

cout<<"选择输入类型:

1int2char";

cin>>i;

if(i==j)

{s.write();

cout<<"请选择排序方式:

1.直接插入排序2.2-路插入3.希尔排序";

cin>>i;

switch(i)

{

case1:

s.InsertionSort();break;

case2:

s.Srsort(s.array);break;

case3:

s.ShellSort(s.array,3);break;

default:

break;

}

s.print();}

else{p.write();

cout<<"请选择排序方式:

1.直接插入排序2.2-路插入3.希尔排序";

cin>>i;

switch(i)

{

case1:

p.InsertionSort();break;

case2:

p.Srsort(p.array);break;

case3:

p.ShellSort(p.array,3);break;

default:

break;

}

p.print();

}

}

在程序的主函数部分,建立了两个实际的类对象s和p,实际类型参数分别为int型和char型。

首先通过选择参数类型来调用读入数组函数,进行数据的输入。

其次选择排序类型,根据所选的类型调用相应的排序函数进行排序。

最后通过输出函数输出排序之后的数据,完成整个程序的编译。

4.4基于控制台的应用程序测试

程序运行结果如图4.1所示。

图4.1数组长度为10的int型数据直接插入排序图

上述结果所应用的排序方法是直接插入排序,接下来下图4.2,图4.3是分别运用2-路插入排序和希尔排序的结果。

图4.2数据长度为10的char型数据2-路插入排序图

图4.3数组长度为8的int型数据希尔排序图

从上述三个图中很容易看出三种排序方法程序运行的正确性。

无论是int型还是char型都能通过所选的排序方法进行正确的排序。

5基于MFC的应用程序

MFC是一个界面开发系统,它提供的类绝大部分界面开发,关联一个窗口的动作。

MFC是WindowsAPI的封装,大大简化了我们的工作。

DOS界面程序采用字符交互式实现数据输入输出,主要通过cin,cout等I/O流实现,而MFC的图形程序界面采用标准Windows窗口和控件实现输入输出,因此必须在MFC类的框架下加入上面所设计的排序算法程序,并通过图形界面的输入输出改造来完成。

5.1基于MFC的应用程序设计

5.1.1MFC程序界面设计

首先在VC中建立MFCAppWizard(exe)工程,名称为PaixuMFC,并在向导的Step1中选择基本对话框,即建立基于对话框的应用程序,如下图5.1,图5.2所示。

 

图5.1建立MFCAppWizard(exe)工程,名称为PaixuMFC

图5.2建立基于对话框的应用程序

将对话框资源中的默认对话框利用工具箱改造成如下界面,如图5.3所示。

 

图5.3利用工具箱建立基本界面

图5.3所示的界面中包含了3个StaticText控件,3个Button控件,和10个EditBox控件,控件的基本信息列表如下表5.1所示。

表5.1控件的基本信息

控件类别

控件ID

控件Caption

说明

StaticText

IDC_STATIC

课程设计---插入排序

输入数组数据

输出排序结果

Botton

IDC_BUTTON1

直接插入排序

IDC_BUTTON2

2-路插入排序

IDC_BUTTON3

希尔排序

EditBox

IDC_EDIT1~IDC_EDIT5

输入的五个数据

IDC_EDIT6~IDC_EDIT10

输出排序之后的五个数据

5.1.2MFC程序代码设计

为了能够将对话框界面上的控件能够与代码联系起来,需要为10个EditBox控件建立MemberVariables,按Ctrl+w键进入MFCClassWizard界面,选择MemberVariables选项卡,可显示成员变量设置界面,如图5.4所示

图5.4设置成员变量

通过该界面设置与10个EditBox控件对应的成员变量,具体如表5.2所示。

表5.2控件基本信息

控件ID

成员变量类型

成员变量名称

IDC_EDIT1~IDC_EDIT5

int

m_w1~m_w5

IDC_EDIT6~IDC_EDIT10

int

m_w6~m_10

下面是编写代码的重要阶段,可以借鉴在设计基于DOS界面的控制台应用程序的代码,并将其作必要的改写,具体内容如下。

①编写直接插入排序按钮的消息处理函数,实现数据排序,具体代码如下:

voidCPaixuMFCDlg:

:

OnButton1()

{inta[10];

intlen=5;

inti,j;

UpdateData(true);

a[1]=m_w1;

a[2]=m_w2;

a[3]=m_w3;

a[4]=m_w4;

a[5]=m_w5;

for(i=2;i<=len;++i)

if(a[i]

{a[0]=a[i];

for(j=i-1;a[0]

a[j+1]=a[j];

a[j+1]=a[0];

}

for(i=0;i<=len;i++)

printf("%d",a[i]);

m_w6=a[1];

m_w7=a[2];

m_w8=a[3];

m_w9=a[4];

m_w10=a[5];

UpdateData(false);

}

②编写2-路插入排序按钮的消息处理函数,实现数据排序,具体代码如下:

voidCPaixuMFCDlg:

:

OnButton2()

{

inta[10];

intlen=5;

inti,j;

UpdateData(true);

a[1]=m_w1;

a[2]=m_w2;

a[3]=m_w3;

a[4]=m_w4;

a[5]=m_w5;

intlow,high;

intd[100];

d[1]=a[1];

intfirst=1;intfinal=1;intm=1;

for(i=2;i<=len;++i)

{

m=(first+final)/2;

if(a[i]

{

low=first;high=m-1;

}

else

{

low=m;high=final;

}

while(low<=high)

{m=(low+high)/2;

if(a[i]

high=m-1;

else

low=m+1;}

if(a[i]>d[m])m++;

for(j=final+1;j>m;j--)

d[j]=d[j-1];

d[m]=a[i];

final++;

}

j=first;

for(i=1;i<=len;++i)

{

a[i]=d[j];++j;

}

for(i=1;i<=len;i++)

printf("%d",a[i]);

m_w6=a[1];

m_w7=a[2];

m_w8=a[3];

m_w9=a[4];

m_w10=a[5];

UpdateData(false);

}

③编写希尔排序按钮的消息处理函数,实现数据排序,具体代码如下:

voidCPaixuMFCDlg:

:

OnButton3()

{inta[10];

intlen=5;

inti,j;

UpdateData(true);

a[1]=m_w1;

a[2]=m_w2;

a[3]=m_w3;

a[4]=m_w4;

a[5]=m_w5;

intk=len/2;;

while(k)

{

for(i=k+1;i<=len;++i)

if(a[i]

{a[0]=a[i];

for(j=i-k;j>0&&(a[0]

a[j+k]=a[j];

a[j+k]=a[0];

}

k=k==2?

1:

k/2;

}

for(i=1;i<=len;i++)

printf("%d",a[i]);

m_w6=a[1];

m_w7=a[2];

m_w8=a[3];

m_w9=a[4];

m_w10=a[5];

UpdateData(false);

}

5.2基于MFC的应用程序测试

运行程序后,首先出现的界面如图5.5所示。

图5.5程序运行界面

然后再输入数据如图5.6

图5.6输入排序数据

单击直接插入排序按钮,实现排序并将排序结果显示出来,如图5.7所示。

图5.7显示直接插入排序结果

第二次输入数据,单击希尔排序按钮,实现排序并将排序结果显示出来,如图5.8所示。

图5.8希尔排序结果图

图5.9直接插入排序结果图

单击确定或取消按钮后,程序能够正常实现退出。

由于是初次进行MFC方面的设计,所以在程序实现过程中遇到了不少问题,比如在希尔排序过程中利用到了函数的调用,这一点在刚开始时连续出错,但是最终还是解决了问题,成功运行了程序,实现了三种插入排序。

通过这次课程设计,对MFC相关的只是也掌握了不少。

 

结论

程序的关键在于建立一个虚拟类模板,然后再类模板中声明各成员函数,这些成员函数在类模板外进行定义,这里要特别注意在类模板外定义成员函数的方法。

除了类模板的基本特征之外,结合问题的实际需要,三种排序方法的算法要具备正确性,可读性,健壮性。

在类模板外定义成员函数时,应写成类模板形式。

不论成员函数在类内定义还是在类外定义,成员函数的代码段都用同一种方式储存,即都不占用对象的存储空间。

一个对象所占的空间大小只取决于该对象中数据成员所占的空间,而与成员函数无关。

函数代码是存储在对象空间之外的。

在程序的主函数部分,建立了两个实际的类对象s和p,实际类型参数分别为int型和char型。

首先通过选择参数类型来调用读入数组函数,进行数据的输入。

其次选择排序类型,根据所选的类型调用相应的排序函数进行排序。

最后通过输出函数输出排序之后的数据,完成整个程序的编译。

程序的成功运行是一个艰辛的过程,如果只是实现一般的功能,将变得容易很多,当加上MFC,不论是效率还是程序可行性,都需要精心设计。

这次做课程设计的过程中,学到了不少MFC的知识和排序的改进算法。

因而以后必须要加强程序MFC方面的训练,这样才能在将编程思想和数据结构转换为代码的时候能得心应手。

自己编好程序上机

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1