北邮数据结构实验 第三次实验 排序

合集下载

北邮计算机网络实践第三次实验报告

北邮计算机网络实践第三次实验报告

计算机网络技术实践实验报告实验名称RIP和OSPF路由协议的配置及协议流程姓名___(-…-)_____________实验日期:2014年4月11日学号_ 242_______实验报告日期:2014年4月16日报告退发:( 订正、重做)一.环境(详细说明运行的操作系统,网络平台,网络拓扑图)1.运行操作系统由于本人电脑上的操作系统是WIN7旗舰版,尝试直接安装Dynamips模拟器,但一直没有成功。

于是在电脑上安装了VMware Workstation,并安装WINXP虚拟操作系统。

在WINXP虚拟操作系统上安装Dynamips模拟器,才顺利完成了实验环境的搭建。

2.网络平台Dynamips模拟器3.网络拓扑图PC2二.实验目的✧复习和进一步掌握实验一二的内容。

✧学会设计较复杂的网络物理拓扑和逻辑网段。

✧掌握路由器上RIP协议的配置方法,能够在模拟环境中进行路由器上RIP协议的配置,并能通过debug信息来分析RIP协议的工作过程,并观察配置水平分割和没有配置水平分割两种情况下RIP协议工作过程的变化。

✧掌握路由器上OSPF协议的配置方法,能够在模拟环境中上进行路由器上OSPF协议的配置,并能够通过debug信息分析OSPF协议的工作工程。

三.实验内容及步骤(包括主要配置流程,重要部分需要截图)1.实验前的基础设置(实验一、二)2.物理拓扑设计修改.net 文件,设计物理拓扑,修改后的.net文件见附录。

3.逻辑网段设计3.1.用list命令列出所有网络成员,如下图所示。

3.2.输入命令start/all启动所有网络成员配置路由器以及PC的idle-pc value并保存。

3.3.同过telnet登陆到主机或路由器打开八个控制台窗口,每个窗口都使用telnet登陆到路由器或主机上。

例如登陆到PC1 的命令为telnet 127.0.0.1 3001,登陆到RT1的命令为telnet 127.0.0.1 30023.4.配置路由器之间的串口并启动串口配置从底层向高层配置,先配置物理层的时钟信息,再配置数据链路层协议,最后配置网络层的IP协议,并开启串口。

北邮数据结构实验报告

北邮数据结构实验报告

北邮数据结构实验报告北京邮电大学信息与通信工程学院2009级数据结构实验报告实验名称:实验三哈夫曼编/解码器的实现学生姓名:陈聪捷日期:2010年11月28日1.实验要求一、实验目的:了解哈夫曼树的思想和相关概念;二、实验内容:利用二叉树结构实现哈夫曼编/解码器1.初始化:能够对输入的任意长度的字符串s进行统计,统计每个字符的频度,并建立哈夫曼树。

2.建立编码表:利用已经建好的哈夫曼树进行编码,并将每个字符的编码输出。

3.编码:根据编码表对输入的字符串进行编码,并将编码后的字符串输出。

4.译码:利用已经建好的哈夫曼树对编码后的字符串进行译码,并输出译码结果。

5.打印:以直观的方式打印哈夫曼树。

6.计算输入的字符串编码前和编码后的长度,并进行分析,讨论哈夫曼编码的压缩效果。

7.用户界面可以设计成“菜单”方式,能进行交互,根据输入的字符串中每个字符出现的次数统计频度,对没有出现的字符一律不用编码。

2.程序分析2.1存储结构二叉树templateclassBiTree{public:BiTree();//构造函数,其前序序列由键盘输入~BiTree(void);//析构函数BiNode*Getroot();//获得指向根结点的指针protected:BiNode*root;//指向根结点的头指针};//声明类BiTree及定义结构BiNodeData:二叉树是由一个根结点和两棵互不相交的左右子树构成data:HCode*HCodeTable;//编码表inttSize;//编码表中的总字符数二叉树的节点结构templatestructBiNode//二叉树的结点结构{Tdata;//记录数据Tlchild;//左孩子Trchild;//右孩子Tparent;//双亲};编码表的节点结构structHCode{chardata;//编码表中的字符charcode[100];//该字符对应的编码};待编码字符串由键盘输入,输入时用链表存储,链表节点为structNode{charcharacter;//输入的字符unsignedintcount;//该字符的权值boolused;//建立树的时候该字符是否使用过Node*next;//保存下一个节点的地址};示意图:2.2关键算法分析1.初始化函数(voidHuffmanTree::Init(stringInput))算法伪代码:1.初始化链表的头结点2.获得输入字符串的第一个字符,并将其插入到链表尾部,n=1(n 记录的是链表中字符的个数)3.从字符串第2个字符开始,逐个取出字符串中的字符3.1将当前取出的字符与链表中已经存在的字符逐个比较,如果当前取出的字符与链表中已经存在的某个字符相同,则链表中该字符的权值加1。

北邮数据结构实验3哈夫曼编码

北邮数据结构实验3哈夫曼编码

数据结构实验报告实验名称:实验3——哈夫曼编码学生姓名:班级:班内序号:学号:日期:2013年11月24日1.实验要求利用二叉树结构实现赫夫曼编/解码器。

基本要求:1、初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个字符的频度,并建立赫夫曼树2、建立编码表(CreateTable):利用已经建好的赫夫曼树进行编码,并将每个字符的编码输出。

3、编码(Encoding):根据编码表对输入的字符串进行编码,并将编码后的字符串输出。

4、译码(Decoding):利用已经建好的赫夫曼树对编码后的字符串进行译码,并输出译码结果。

5、打印(Print):以直观的方式打印赫夫曼树(选作)6、计算输入的字符串编码前和编码后的长度,并进行分析,讨论赫夫曼编码的压缩效果。

2. 程序分析2.1存储结构:struct HNode{char c;//存字符内容int weight;int lchild, rchild, parent;};struct HCode{char data;char code[100];}; //字符及其编码结构class Huffman{private:HNode* huffTree; //Huffman树HCode* HCodeTable; //Huffman编码表public:Huffman(void);void CreateHTree(int a[], int n); //创建huffman树void CreateCodeTable(char b[], int n); //创建编码表void Encode(char *s, string *d); //编码void Decode(char *s, char *d); //解码void differ(char *,int n);char str2[100];//数组中不同的字符组成的串int dif;//str2[]的大小~Huffman(void);};结点结构为如下所示:三叉树的节点结构:struct HNode//哈夫曼树结点的结构体{ int weight;//结点权值int parent;//双亲指针int lchild;//左孩子指针int rchild;//右孩子指针char data;//字符};示意图为:int weight int parent int lchild int rchild Char c 编码表节点结构:struct HCode//编码表结构体{char data;//字符char code[100];//编码内容};示意图为:基本结构体记录字符和出现次数:struct node{int num;char data;};示意图为:2.关键算法分析(1).初始化:伪代码:1.输入需要编译的文本内容2.将输入的内容保存到数组str1中3.统计出现的字符数目,并且保存到变量count中4.统计出现的不同的字符,存到str2中,将str2的大小存到dif中时间复杂度O(n!)(2).创建哈夫曼树算法伪代码:1.创建一个长度为2*n-1的三叉链表2.将存储字符及其权值的链表中的字符逐个写入三叉链表的前n个结点的data域,并将对应结点的孩子域和双亲域赋为空3.从三叉链表的第n个结点开始,3.1从存储字符及其权值的链表中取出两个权值最小的结点x,y,记录其下标x,y。

数据结构实验三实验报告

数据结构实验三实验报告

数据结构实验三实验报告数据结构实验三实验报告一、实验目的本次实验的目的是通过实践掌握树的基本操作和应用。

具体来说,我们需要实现一个树的数据结构,并对其进行插入、删除、查找等操作,同时还需要实现树的遍历算法,包括先序、中序和后序遍历。

二、实验原理树是一种非线性的数据结构,由结点和边组成。

树的每个结点都可以有多个子结点,但是每个结点只有一个父结点,除了根结点外。

树的基本操作包括插入、删除和查找。

在本次实验中,我们采用二叉树作为实现树的数据结构。

二叉树是一种特殊的树,每个结点最多只有两个子结点。

根据二叉树的特点,我们可以使用递归的方式实现树的插入、删除和查找操作。

三、实验过程1. 实现树的数据结构首先,我们需要定义树的结点类,包括结点值、左子结点和右子结点。

然后,我们可以定义树的类,包括根结点和相应的操作方法,如插入、删除和查找。

2. 实现插入操作插入操作是将一个新的结点添加到树中的过程。

我们可以通过递归的方式实现插入操作。

具体来说,如果要插入的值小于当前结点的值,则将其插入到左子树中;如果要插入的值大于当前结点的值,则将其插入到右子树中。

如果当前结点为空,则将新的结点作为当前结点。

3. 实现删除操作删除操作是将指定的结点从树中移除的过程。

我们同样可以通过递归的方式实现删除操作。

具体来说,如果要删除的值小于当前结点的值,则在左子树中继续查找;如果要删除的值大于当前结点的值,则在右子树中继续查找。

如果要删除的值等于当前结点的值,则有三种情况:- 当前结点没有子结点:直接将当前结点置为空。

- 当前结点只有一个子结点:将当前结点的子结点替代当前结点。

- 当前结点有两个子结点:找到当前结点右子树中的最小值,将其替代当前结点,并在右子树中删除该最小值。

4. 实现查找操作查找操作是在树中寻找指定值的过程。

同样可以通过递归的方式实现查找操作。

具体来说,如果要查找的值小于当前结点的值,则在左子树中继续查找;如果要查找的值大于当前结点的值,则在右子树中继续查找。

数据结构实验报告-排序

数据结构实验报告-排序

数据结构实验报告-排序一、实验目的本实验旨在探究不同的排序算法在处理大数据量时的效率和性能表现,并对比它们的优缺点。

二、实验内容本次实验共选择了三种常见的排序算法:冒泡排序、快速排序和归并排序。

三个算法将在同一组随机生成的数据集上进行排序,并记录其性能指标,包括排序时间和所占用的内存空间。

三、实验步骤1. 数据的生成在实验开始前,首先生成一组随机数据作为排序的输入。

定义一个具有大数据量的数组,并随机生成一组在指定范围内的整数,用于后续排序算法的比较。

2. 冒泡排序冒泡排序是一种简单直观的排序算法。

其基本思想是从待排序的数据序列中逐个比较相邻元素的大小,并依次交换,从而将最大(或最小)的元素冒泡到序列的末尾。

重复该过程直到所有数据排序完成。

3. 快速排序快速排序是一种分治策略的排序算法,效率较高。

它将待排序的序列划分成两个子序列,其中一个子序列的所有元素都小于等于另一个子序列的所有元素。

然后对两个子序列分别递归地进行快速排序。

4. 归并排序归并排序是一种稳定的排序算法,使用分治策略将序列拆分成较小的子序列,然后递归地对子序列进行排序,最后再将子序列合并成有序的输出序列。

归并排序相对于其他算法的优势在于其稳定性和对大数据量的高效处理。

四、实验结果经过多次实验,我们得到了以下结果:1. 冒泡排序在数据量较小时,冒泡排序表现良好,但随着数据规模的增大,其性能明显下降。

排序时间随数据量的增长呈平方级别增加。

2. 快速排序相比冒泡排序,快速排序在大数据量下的表现更佳。

它的排序时间线性增长,且具有较低的内存占用。

3. 归并排序归并排序在各种数据规模下都有较好的表现。

它的排序时间与数据量呈对数级别增长,且对内存的使用相对较高。

五、实验分析根据实验结果,我们可以得出以下结论:1. 冒泡排序适用于数据较小的排序任务,但面对大数据量时表现较差,不推荐用于处理大规模数据。

2. 快速排序是一种高效的排序算法,适用于各种数据规模。

北邮数据结构实验报告

北邮数据结构实验报告

北邮数据结构实验报告摘要:本报告基于北邮数据结构实验,通过实际操作和实验结果的分析,总结和讨论了各实验的目的、实验过程、实验结果以及相关的问题和解决方法。

本报告旨在帮助读者了解数据结构实验的基本原理和应用,并为今后的学习和研究提供参考。

1. 实验一:线性表的操作1.1 实验目的本实验旨在掌握线性表的基本操作以及对应的算法实现,包括插入、删除、查找、修改等。

1.2 实验过程我们使用C++语言编写了线性表的相关算法,并在实际编程环境下进行了测试。

通过插入元素、删除元素、查找元素和修改元素的操作,验证了算法的正确性和效率。

1.3 实验结果经过测试,我们发现线性表的插入和删除操作的时间复杂度为O(n),查找操作的时间复杂度为O(n),修改操作的时间复杂度为O(1)。

这些结果与预期相符,并反映了线性表的基本特性。

1.4 问题与解决方法在实验过程中,我们遇到了一些问题,例如插入操作的边界条件判断、删除操作时的内存释放等。

通过仔细分析问题,我们优化了算法的实现,并解决了这些问题。

2. 实验二:栈和队列的应用2.1 实验目的本实验旨在掌握栈和队列的基本原理、操作和应用,并进行实际编程实现。

2.2 实验过程我们使用C++语言编写了栈和队列的相关算法,并在实际编程环境下进行了测试。

通过栈的应用实现表达式求值和逆波兰表达式的计算,以及队列的应用实现图的广度优先遍历,验证了算法的正确性和效率。

2.3 实验结果经过测试,我们发现栈的应用可以实现表达式的求值和逆波兰表达式的计算,队列的应用可以实现图的广度优先遍历。

这些结果证明了栈和队列在实际应用中的重要性和有效性。

2.4 问题与解决方法在实验过程中,我们遇到了一些问题,例如中缀表达式转后缀表达式的算法设计、表达式求值的优化等。

通过查阅资料和与同学的讨论,我们解决了这些问题,并完善了算法的实现。

3. 实验三:串的模式匹配3.1 实验目的本实验旨在掌握串的基本操作和模式匹配算法,并进行实际编程实现。

北京邮电大学 数据结构 实验三 简单数组排序的设计

北京邮电大学 数据结构 实验三  简单数组排序的设计

数据结构实验报告实验名称:实验3——简单数组实现排序学生姓名:XXXXNB班级:XXXXXXXX班内序号:学号:XXXXXXXX日期:2016年XXXXXXX1.实验要求使用简单数组实现下面各种排序算法,并进行比较。

排序算法:1、插入排序2、希尔排序3、冒泡排序4、快速排序5、简单选择排序6、堆排序(选作)7、归并排序(选作)8、基数排序(选作)9、其他要求:1、测试数据分成三类:正序、逆序、随机数据2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换计为3次移动)。

//3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微秒(选作)4、对2和3的结果进行分析,验证上述各种算法的时间复杂度编写测试main()函数测试线性表的正确性。

2.程序分析在题目中要求测试不同的数据,可以手动输入待排序元素。

我在编程时为了界面的简洁易于监控,便选择了在主程序中把数组写好放入主程序里。

同时为了方便每种算法的比较,我将所有的函数包装为一个类,方便运行并监控。

比较遗憾的是,我没有做算法运行时间的相关程序,为了弥补这种缺陷,我选择了将界面做的更人性化一些。

2.1 存储结构采用数组进行顺序存储结构示意图如下:2.2 关键算法分析核心算法思想:1. 利用教材讲述的基本算法思想,实现其中五种排序算法,统计其运行相关数据。

2. 将五种排序函数封装到一个类中,使得程序代码可读性、结构更加优化。

排序算法分析:1.插入排序算法插入排序的思想是:每次从无序区取一元素将其添加到有序区中。

a.直接插入排序C++描述如下,其中形参a[]为待排序数组,n为待排序元素个数同时添加两个变量move,compare用于记录整个排序过程中的比较次数以及移动次数void Sort::DirectInsertSort(int a[], int n)//直接插入排序{int k;int move = 0;int compare=0;for (int i = 2; i <= n; i++)//第一个定然为有序,出现两个数据时开始进行排序{if (a[i] < a[i - 1]){a[0] = a[i];move++;//元素赋值移动+1for (int j = i - 1; j > 0 && a[0] < a[j]; j-- ){a[j + 1] = a[j];move++;//移动+1compare++;//for条件中比较+1k = j;//记录查找出的位置}a[k] = a[0];move++;//元素赋值移动+1}compare++;//if比较n大小+1}cout << "移动次数" << move << endl;cout << "比较次数" << compare << endl;}b.希尔排序希尔排序,设待排序对象序列有n个元素,先取d<n,比如d=n/2,作为间隔,将全部对象分为d个子序列,对每一个子序列分别进行直接插入排序,然后缩小间隔d,即减少子序列个数例如取d=d/2,重复子序列的划分和排序工作,直到取d=1,仅有一个子序列为止(ps:本质上仍为直接插入排序的改进)C++描述如下,其中形参a[]为待排序数组,n为待排序元素个数同时添加两个变量move,compare用于记录整个排序过程中的比较次数以及移动次数void Sort::ShellInsert(int a[], int n)//希尔排序,本质上为直接插入排序的改进{int k;int move = 0;int compare = 0;for (int d = n / 2; d >= 1; d = d / 2){for (int i = d + 1; i <= n; i++)//前d个元素是每个子序列头部,为初始有序区,从d + 1开始循环{if (a[i] < a[i - d])//并不是单独分别对各个子集分别排序,而是依次从每个子集第二个元素排起{a[0] = a[i];move++;//赋值移动+1for (int j = i - d; j > 0 && a[j] > a[0]; j = j - d){a[j + d] = a[j];move++;//元素后移+1compare++;//for循环中条件比较+1k = j;}a[k] = a[0];move++;//元素赋值移动+1}compare++;//if中比较+1}}cout << "移动次数" << move << endl;cout << "比较次数" << compare << endl;}//希尔排序利用了直接排序的两个特点:1.基本有序直接插入最快 2.记录个数很少的无序序列,直接插入也很快。

北邮数据结构实验第三次实验排序

北邮数据结构实验第三次实验排序

数据结构实验报告1.实验要求(1)实验目的通过选择下面两个题目之一,学习、实现、对比各种排序算法,掌握各种排序算法的优劣,以及各种算法使用的情况。

(2)实验内容使用简单数组实现下面各种排序算法,并进行比较。

排序算法:1、插入排序2、希尔排序3、冒泡排序4、快速排序5、简单选择排序6、堆排序(选作)7、归并排序(选作)8、基数排序(选作)9、其他要求:1、测试数据分成三类:正序、逆序、随机数据2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换计为3次移动)。

3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微秒(选作)4、对2和3的结果进行分析,验证上述各种算法的时间复杂度编写测试main()函数测试排序算法的正确性。

2. 程序分析2.1 存储结构顺序表:示意图:2.2 关键算法分析(1)测试数据的产生:正序、逆序、随机数据用两个数组实现乱序、顺序以及逆序数据的排序。

基本思想为:随机序列产生一个指定长度的乱序序列,然后通过memcpy()函数拷贝到第二个数组里,第二个数组作为乱序序列的保存数组,每次对第一个数组进行排序,之后拷贝第二个数组中的乱序序列到第一个数组,实现各次乱序排列。

只要算法正确(第一步可以检验),之后顺序排列只需反复对第一个数组进行操作即可,再后用第二个数组保存逆序数组,然后同样在每次排序之后复制第二数组存储的乱序序列到第一组,对第一组反复排序即可。

<1> pRandom1=new long int[Max+1];pRandom2=new long int[Max+1];<2> srand((unsigned)time(NULL)); for(int i = 1; i <= Max;i++ ) pRandom2[i]=rand();<3> memcpy(obj.pRandom1,obj.pRandom2,(Max+1)*sizeof(long int));(2)排序算法:<1>插入排序:依次将待排序的序列中的每一个记录插入到先前排序好的序列中,直到全部记录排序完毕。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据结构实验报告1.实验要求(1)实验目的通过选择下面两个题目之一,学习、实现、对比各种排序算法,掌握各种排序算法的优劣,以及各种算法使用的情况。

(2)实验内容使用简单数组实现下面各种排序算法,并进行比较。

排序算法:1、插入排序2、希尔排序3、冒泡排序4、快速排序5、简单选择排序6、堆排序(选作)7、归并排序(选作)8、基数排序(选作)9、其他要求:1、测试数据分成三类:正序、逆序、随机数据2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换计为3次移动)。

3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微秒(选作)4、对2和3的结果进行分析,验证上述各种算法的时间复杂度编写测试main()函数测试排序算法的正确性。

2. 程序分析2.1 存储结构顺序表:示意图:2.2 关键算法分析(1)测试数据的产生:正序、逆序、随机数据用两个数组实现乱序、顺序以及逆序数据的排序。

基本思想为:随机序列产生一个指定长度的乱序序列,然后通过memcpy()函数拷贝到第二个数组里,第二个数组作为乱序序列的保存数组,每次对第一个数组进行排序,之后拷贝第二个数组中的乱序序列到第一个数组,实现各次乱序排列。

只要算法正确(第一步可以检验),之后顺序排列只需反复对第一个数组进行操作即可,再后用第二个数组保存逆序数组,然后同样在每次排序之后复制第二数组存储的乱序序列到第一组,对第一组反复排序即可。

<1> pRandom1=new long int[Max+1];pRandom2=new long int[Max+1];<2> srand((unsigned)time(NULL)); for(int i = 1; i <= Max;i++ ) pRandom2[i]=rand();<3> memcpy(obj.pRandom1,obj.pRandom2,(Max+1)*sizeof(long int));(2)排序算法:<1>插入排序:依次将待排序的序列中的每一个记录插入到先前排序好的序列中,直到全部记录排序完毕。

/1/int j=0;/2/ for(int i =2; i <= Max;i++) parray[0]=parray[i];comparetimes[0]++;/4/parray[j+1]=parray[0];movetimes[0]+=2;示意图:r1,r2,r3,…,ri-1,ri,ri+1,…,rn有序区待插入无序区<2>希尔排序:先将整个序列分割成若干个子列,分别在各个子列中运用直接插入排序,待整个序列基本有序时,再对全体记录进行一次直接插入排序。

int Sort::ShellSort(long int parray[]){int j=0;for(int d=Max/2;d>=1;d/=2){for(int i=d+1;i<=Max;i++){ parray[0]=parray[i];comparetimes[1]++;for(j=i-d;j>0 && parray[0]<parray[j];j-=d){ parray[j+d]=parray[j];movetimes[1]++;}parray[j+d]=parray[0];movetimes[1]+=2;}}return 0;}<3>冒泡排序:两两比较相邻记录的关键码,如果反序则交换,直到没有反序记录为止。

int Sort::BubbleSort(long int parray[]){ int exchange=Max;int bound,j;while(exchange){ bound=exchange;exchange=0;for(j=1;j<bound;j++){ comparetimes[2]++;if(parray[j]>parray[j+1]){ parray[0]=parray[j];parray[j]=parray[j+1];parray[j+1]=parray[0];exchange=j;movetimes[2]+=3;}}}return 0;}示意图:r1,r2,r3,…,ri-1,ri,ri+1,…,rn反序则交换有序区<4>快速排序:首先选择一个基准,将记录分割为两部分,左支小于或等于基准,右支则大于基准,然后对两部分重复上述过程,直至整个序列排序完成。

int Sort::QuickSort(long int parray[]){QuickSortRecursion(parray,1, Max);return 0;}int Sort::QuickSortRecursion(long int parray[], int first=1, int end=Max) {if (first<end){ int pivot=QuickSortPatition(parray, first, end);QuickSortRecursion(parray, first, pivot-1);//左侧子序列排序QuickSortRecursion(parray, pivot+1, end); //右侧子序列排序} return 0;}int Sort::QuickSortPatition(long int r[], int first, int end ){int i=first;int j=end; int temp;while (i<j){ while (i<j && r[i]<= r[j]){j--;comparetimes[3]++; } //右侧扫描 if (i<j){ temp=r[i]; //将较小记录交换到前面r[i]=r[j];r[j]=temp;i++;movetimes[3]+=3; }while (i<j && r[i]<= r[j]){i++;comparetimes[3]++;} //左侧扫描if (i<j){temp=r[j];r[j]=r[i];r[i]=temp; //将较大记录交换到后面j--;movetimes[3]+=3; } }return i; //i为轴值记录的最终位置示意图:r1,r2,r3,…,ri-1,ri,ri+1,…,rnr<ri 轴值 r>ri<5>选择排序:从待排序的记录序列中选择关键码最小(或最大)的记录并将它与序列中的第一个记录交换位置;然后从不包括第一个位置上的记录序列中选择关键码最小(或最大)的记录并将它与序列中的第二个记录交换位置;如此重复,直到序列中只剩下一个记录为止。

int Sort::SelectSort(long int parray[]){int i,j,index,temp;for (i=1; i<Max; i++) //对n个记录进行n-1趟简单选择排序 {index=i;for (j=i+1; j<=Max; j++){comparetimes[4]++; //在无序区中选取最小记录if (parray[j]<parray[index])index=j;}if (index!=i){temp=parray[i];parray[i]=parray[index];parray[index]=temp;movetimes[4]+=3;}}示意图:r1,r2,r3,…,ri-1,ri,ri+1,…,rn反序则交换有序区<6>堆排序:通过建立大根堆或者小根堆,取出根节点,反复调整堆使之保持大根堆或者小根堆,直至最后序列有序。

int Sort::HeapSort(long int parray[]){int i;for (i=Max/2; i>=1; i--)HeapSortSift(parray, i, Max) ;for (i=1; i<Max; i++){parray[0]=parray[Max-i+1];parray[Max-i+1]=parray[1];parray[1]=parray[0];movetimes[5]+=3;HeapSortSift(parray, 1, Max-i);}return 0;}void Sort::HeapSortSift(long int parray[], int k, int m){int i,j;i=k;j=2*i; //置i为要筛的结点,j为i的左孩子while (j<=m) //筛选还没有进行到叶子{if (j<m && parray[j]<parray[j+1]){j++;comparetimes[5]++;} //比较i的左右孩子,j为较大者 if (parray[i]>parray[j]){comparetimes[5]++;break;} //根结点已经大于左右孩子中的较大者else{parray[0]=parray[i];parray[i]=parray[j];parray[j]=parray[0];movetimes[5]+=3;i=j;j=2*i; //被筛结点位于原来结点j的位置<7>归并排序:将若干个有序序列两两归并,直至所有待排序的记录都在一个有序序列为止。

int Sort::MergeSort(long int parray[]){long int r1[Max+1];int h(1);while (h<Max){MergePass(parray, r1, h); //归并h=2*h;MergePass(r1, parray, h);h=2*h;}return 0;}void Sort::Merge(long int parray[], long int r1[], int s, int m, int t) //一次归并{int i=s;int j=m+1;int k=s;while (i<=m && j<=t){comparetimes[6]++;movetimes[6]++;if (parray[i]<=parray[j]){r1[k++]=parray[i++];}elser1[k++]=parray[j++];}if (i<=m)while (i<=m){r1[k++]=parray[i++];movetimes[6]++;}elsewhile (j<=t){r1[k++]=parray[j++];movetimes[6]++;}}void Sort::MergePass(long int parray[], long int r1[], int h) //一趟归并{int i(1),k;while (i<=Max-2*h+1){Merge(parray, r1, i, i+h-1, i+2*h-1);i+=2*h;}if (i<Max-h+1)Merge(parray, r1, i, i+h-1, Max);else for (k=i; k<=Max; k++){r1[k]=parray[k];movetimes[6]++;(3)比较上述排序算法中关键字的比较次数和移动次数:使用函数指针数组,分别指向各排序函数的入口地址,然后在Statistics()函数中加以调用,使得排序函数运行在统计时间函数之间,这样使用一个for语句即可实现算法的一次性调用、时间统计、移动次数和比较次数统计。

相关文档
最新文档