实验时间 | 2024年 4 月10日19时至22时 | 学时数 | 3 |
1.实验名称 分治与减治算法实验:题目5 排序中减治法的程序设计 | |||
2.实验目的 (1)掌握堆的有关概念; (2)掌握堆排序的基本思想和其算法的实现过程; (3)熟练掌握筛选算法的实现过程; (4)在掌握的基础上编程实现堆排序的具体实现过程。 | |||
3.实验内容 给出一个记录序列,用堆排序的方法将其进行升序排列,输出结果,输出时要求有文字说明。请任选一种语言编写程序实现上述算法,并分析其算法复杂度。 | |||
堆的有关概念:应用堆排序(heap sort)方法对一个记录序列进行升序排列。堆(heap)是具有下列性质的完全二叉树:每个结点的值都小于或等于其左右孩子结点的值(小根堆):或者每个结点的值都大于或等于其左右孩子结点的值(大根堆)。以结点的层序编号作为下标,将堆用顺序存储结构(即数组)来存储,则堆对应于一组序列 堆排序的基本思想:堆排序是利用堆(假设利用大根堆)的特性进行排序的方法,其基本思想是:首先将待排序的记录序列构造成一个堆,此时,堆顶记录是堆中所有记录的最大者,将它从堆中移走(通常将堆顶记录和堆中最后一个记录交换),然后将剩余记录再调整成堆,这样又找出了次大记录,依此类推,直到堆中只有一个记录为止。 筛选算法的实现过程:在堆调整的过程中,总是将根结点(即被调整结点)与左右子树的根结点进行比较,若不满足堆的条件,则将根结点与左右子树根结点的较大者进行交换,这个调整过程一直进行到所有子树均为堆或将被调整的结点(即原来的根结点)交换到叶子为止。这个自堆顶至叶子的调整过程称为筛选(sieve)。
| |||
9.实验源代码和伪代码 堆排序首先将无序序列调整成堆,由于叶子结点均可看成是堆,因此,可以从编号最大的分支结点直至根结点反复调用筛选算法。注意,C++语言的数组下标从0开始,则r[i]的左孩子是r[2i+1],r[i]的右孩子是r[2i+2]。根结点(即堆顶记录)存储在r[0],一般情况下,第i趟排序的堆中有n-i+1个记录,即堆中最后一个记录是r[n-i],将r[0]与r[n-i]相交换;第i趟排序后,无序区有n-i个记录,在无序区对应的完全二叉树中,只需筛选根结点即可重新建堆。堆排序算法用C语言描述如下:
时间复杂度分析: 算法Sift将根结点与左右子树的根结点进行比较,若不满足堆的条件,则将根结点与左右子树根结点的较大者进行交换,所以,每比较一次,需要调整的完全叉树的问题规模就减少一半,因此,其时间性能是O(logn)。 | |||
代码运行截图: 心得: 对减治法有了进一步理解。 |
分治与减治算法实验:题目5 排序中减治法的程序设计
于 2024-04-15 20:27:59 首次发布