分治与减治算法实验:题目5 排序中减治法的程序设计

实验时间

2024年 4 月10日19时至22时

学时数

3

1.实验名称

分治与减治算法实验:题目5 排序中减治法的程序设计

2.实验目的

(1)掌握堆的有关概念;

(2)掌握堆排序的基本思想和其算法的实现过程;

(3)熟练掌握筛选算法的实现过程;

(4)在掌握的基础上编程实现堆排序的具体实现过程。

3.实验内容

给出一个记录序列,用堆排序的方法将其进行升序排列,输出结果,输出时要求有文字说明。请任选一种语言编写程序实现上述算法,并分析其算法复杂度。

  1. 实验原理

堆的有关概念:应用堆排序(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语言描述如下:

#include <iostream>

using namespace std;

void heapsort (int r[], int n);

void SiftHeap(int r[], int k, int n);

void SiftHeap(int r[], int k, int n) {

int i, j, temp;

i = k;//置i为要筛的结点,j为i的左孩子

j = 2 * i + 1;

while (j < n) {//筛选还没有进行到叶子

if (j < n - 1 && r[j] < r[j + 1])

j++;//比较i的左右孩子,j为较大者

if (r[i] > r[j]) //根结点已经大于左右孩子中的较大者

break;

else {

temp = r[i];

r[i] = r[j];

r[j] = temp; //将被筛结点与结点j交换

i = j;

j = 2 * i + 1; //被筛结点位于原来结点j的位置

}

}

}

void heapsort (int r[], int n) {

int i, temp;

for (i = (n - 1) / 2; i >= 0; i--) //初始建堆,最后一个分支的下标是(n-1)/2

SiftHeap(r, i, n);

for (i = 1; i <= n - 1 ; i++) { //重复执行移走堆顶及重建堆的操作

temp = r[0];

r[0] = r[n - i];

r[n - i] = temp;

SiftHeap(r, 0, n - i); //只需调整根结点

}

}

int main() {

int n, r[100], k;

cout << "请输入元素个数:";

cin >> n;

cout << "请输入各元素" << endl;

for (int i = 0; i < n; i++) {

cin >> r[i];

}

SiftHeap(r, k, n);

heapsort (r, n);

cout << "最终的堆为:" << endl;

for (int i = 0; i < n; i++) {

cout << r[i] << " ";

}

}

时间复杂度分析:

算法Sift将根结点与左右子树的根结点进行比较,若不满足堆的条件,则将根结点与左右子树根结点的较大者进行交换,所以,每比较一次,需要调整的完全叉树的问题规模就减少一半,因此,其时间性能是O(logn)。

  1. 实验结论及心得

代码运行截图:

心得:

对减治法有了进一步理解。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值