堆排序初始堆的建立图解(堆排序构建初始堆)

http://www.itjxue.com  2023-01-26 19:20  来源:未知  点击次数: 

初始堆后堆排序

我说的是建立最小堆,最大堆同理可得

首先建立完全二叉树

45

28 49

16 37 82 56

75

从n/2个节点开始选择,第一趟,16比75小,不换.到n/2-1个节点,49和82、56比,49小,也不换.到n/2-2个结点,28和16、37比,16小,变成

45

16 49

28 37 82 56

75

45和16、49比,16最小,换

16

45 49

28 37 82 56

75

45和28、37比,28最小

16

28 49

45 37 82 56

75

最小初始堆建好了,到输出,首先75和16换,输出16

75

28 49

45 37 82 56

16

将剩下的元素建成堆

28

37 49

45 75 82 56

16

56和28换,输出28

56

37 49

45 75 82 28

16

再建初始堆

37

45 49

56 75 82 28

16

82和37换,输出37

82

45 49

56 75 37 28

16

建初始堆

45

56 49

82 75 37 28

16

75和45换,输出45

75

56 49

82 45 37 28

16

建初始堆

49

56 75

82 45 37 28

16

82和49换,输出49

82

56 75

49 45 37 28

16

建初始堆

56

82 75

49 45 37 28

16

75和56换,输出56

75

82 56

49 45 37 28

16

建初始堆

75

82 56

49 45 37 28

16

82和75换,输出75

82

75 56

49 45 37 28

16

输出82

82

75 56

49 45 37 28

16

得到有序序列82,75,56,49,45,37,28,16,是按从小到大输出的,如果要按从大到小输出,建初始堆的时候,建最大堆就可以了,规律似乎看不出来

堆排序过程

1,实用的排序算法:选择排序

(1)选择排序的基本思想是:每一趟(例如第i趟,i=0,1,2,3,……n-2)在后面n-i个待排序元素中选择排序码最小的元素,作为有序元素序列的第i个元素。待到第n-2趟做完,待排序元素只剩下一个,就不用再选了。

(2)三种常用的选择排序方法

1直接选择排序

2锦标赛排序

3堆排序

其中,直接排序的思路和实现都比较简单,并且相比其他排序算法,直接选择排序有一个突出的优势——数据的移动次数少。

(3)直接选择排序简介

1直接选择排序(select sort)是一种简单的排序方法,它的基本步骤是:

1)在一组元素V[i]~V[n-1]中选择具有最小排序码的元素;

2)若它不是这组元素中的第一个元素,则将它与这组元素中的第一个元素对调;

3)在这组元素中剔除这个具有最小排序码的元素,在剩下的元素V[i+1]~V[n-1]中重复执行1、2步骤,直到剩余元素只有一个为止。

2直接选择排序使用注意

它对一类重要的元素序列具有较好的效率,这就是元素规模很大,而排序码却比较小的序列。因为对这种序列进行排序,移动操作所花费的时间要比比较操作的时间大的多,而其他算法移动操作的次数都要比直接选择排序来的多,直接选择排序是一种不稳定的 排序方法。

3直接选择排序C++函数代码

//函数功能,直接选择排序算法对数列排序

//函数参数,数列起点,数列终点

void dselect_sort(const int start, const int end) {

for (int i = start; i end; ++i) {

int min_position = i;

for (int j = i + 1; j = end; ++j) { //此循环用来寻找最小关键码

if (numbers[j] numbers[min_position]) {

min_position = j;

}

}

if (min_position != i) { //避免自己与自己交换

swap(numbers[min_position], numbers[i]);

(4)关于锦标赛排序

直接选择排序中,当n比较大时,排序码的比较次数相当多,这是因为在后一趟比较选择时,往往把前一趟已经做过的比较又重复了一遍,没有把前一趟的比较结果保留下来。

锦标赛排序(tournament sort)克服了这一缺点。它的思想与体育比赛类似,就是把待排序元素两两进行竞赛,选出其中的胜利者,之后胜利者之间继续竞赛,再选出其中的胜利者,然后重复这一过程,最终构造出胜者树,从而实现排序的目的。

2,堆排序的排序过程

(1)个人理解:堆排序是选择排序的一种,所以它也符合选择排序的整体思想。直接选择排序是在还未成序的元素中逐个比较选择,而堆排序是首先建立一个堆(最大堆或最小堆),这使得数列已经“大致”成序,之后只需要局部调整来重建堆即可。建立堆及重建堆这一过程映射到数组中,其实就是一个选择的过程,只不过不是逐个比较选择,而是借助完全二叉树来做到有目的的比较选择。这也是堆排序性能优于直接选择排序的一个体现。

(2)堆排序分为两个步骤:

1根据初始输入数据,利用堆的调整算法形成初始堆;

2通过一系列的元素交换和重新调整堆进行排序。

(3)堆排序的排序思路

1前提,我们是要对n个数据进行递增排序,也就是说拥有最大排序码的元素应该在数组的末端。

2首先建立一个最大堆,则堆的第一个元素heap[0]具有最大的排序码,将heap[0]与heap[n-1]对调,把具有最大排序码的元素交换到最后,再对前面n-1个元素,使用堆的调整算法siftDown(0,n-2),重新建立最大堆。结果具有次最大排序码的元素又浮到堆顶,即heap[0]的位置,再对调heap[0]与heap[n-2],并调用siftDown(0,n-3),对前n-2个元素重新调整,……如此反复,最后得到一个数列的排序码递增序列。

(4)堆排序的排序过程:

下面给出局部调整成最大堆的函数实现siftDown(),这个函数在前面最小堆实现博文中的实现思路已经给出,只需做微小的调整即可用在这里建立最大堆。

C语言堆排序法谁能通俗易懂又清晰地讲解一下?谢谢

您可以找本数据结构的书看看,比如清华严尉敏的《数据结构》

以下摘抄于 这个网站的讲解挺不错,您可以看看

1、 堆排序定义

 n个关键字序列Kl,K2,…,Kn称为堆,当且仅当该序列满足如下性质(简称为堆性质):

 (1) ki≤K2i且ki≤K2i+1 或(2)Ki≥K2i且ki≥K2i+1(1≤i≤ )

 若将此序列所存储的向量R[1..n]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。

3、堆排序特点

 堆排序(HeapSort)是一树形选择排序。

 堆排序的特点是:在排序过程中,将R[l..n]看成是一棵完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系【参见二叉树的顺序存储结构】,在当前无序区中选择关键字最大(或最小)的记录。

5、堆排序

堆排序利用了大根堆(或小根堆)堆顶记录的关键字最大(或最小)这一特征,使得在当前无序区中选取最大(或最小)关键字的记录变得简单。

(1)用大根堆排序的基本思想

① 先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区

② 再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换,由此得到新的无序区R[1..n-1]和有序区R[n],且满足R[1..n-1].keys≤R[n].key

③由于交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆。然后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换,由此得到新的无序区R[1..n-2]和有序区R[n-1..n],且仍满足关系R[1..n-2].keys≤R[n-1..n].keys,同样要将R[1..n-2]调整为堆。

……

直到无序区只有一个元素为止。

(2)大根堆排序算法的基本操作:

① 初始化操作:将R[1..n]构造为初始堆;

② 每一趟排序的基本操作:将当前无序区的堆顶记录R[1]和该区间的最后一个记录交换,然后将新的无序区调整为堆(亦称重建堆)。

注意:

①只需做n-1趟排序,选出较大的n-1个关键字即可以使得文件递增有序。

②用小根堆排序与利用大根堆类似,只不过其排序结果是递减有序的。堆排序和直接选择排序相反:在任何时刻,堆排序中无序区总是在有序区之前,且有序区是在原向量的尾部由后往前逐步扩大至整个向量为止。

(3)堆排序的算法:

void HeapSort(SeqIAst R)

{ //对R[1..n]进行堆排序,不妨用R[0]做暂存单元

int i;

BuildHeap(R); //将R[1-n]建成初始堆

for(i=n;i1;i--){ //对当前无序区R[1..i]进行堆排序,共做n-1趟。

R[0]=R[1];R[1]=R[i];R[i]=R[0]; //将堆顶和堆中最后一个记录交换

  Heapify(R,1,i-1); //将R[1..i-1]重新调整为堆,仅有R[1]可能违反堆性质

} //endfor

} //HeapSort

(责任编辑:IT教学网)

更多

推荐金山WPS文章