堆排序相对冒泡排序,选择排序效率很高,不再是O (n ^ 2)。
假若将一个序列<强> >强排序好,那么我们来考虑最大堆还是最小堆来排序。假若是最小堆的话,堆的顶端必定是堆中的最小值,这样貌似可以。但是,如果是它的(一边或)子树左子树的节点数据值大于(一边或)右子树的节点数据值,直接打印肯定是错误的,而且对于此时的堆我们也无法操控来调整好正确的顺序了。
那我们换成最大堆来实现升序想,当我们把序列调整成为最大堆后,最大堆顶端的数据值是最大的,然后我们将这个最大值与堆的最后一个叶子节点值来进行交换,再将交换后的顶端值进行调整,换到合适的位置处……重复这样的工作,注意:进行第2次交换就要将顶端元素值与倒数第2个节点元素值交换了,且调整顶端元素位置也不能一直调整到大小是1处。(因为:大小是1处的值已经是最大)
代码如下:
# define _CRT_SECURE_NO_WARNINGS 1 # includeusing namespace 性传播疾病; # include void AdjustDown (int *, int 父母,,int 大小) { ,,,int child =, 2, *, parent +, 1; ,,,while (child & lt;,大小) ,,,{ ,,,,,,,if (child +, 1, & lt;, size ,,,一个(孩子),& lt;,一个[child +, 1]) ,,,,,,,{ ,,,,,,,,,,,+ +孩子; ,,,,,,,} ,,,,,,,if ((孩子)在一个(父)) ,,,,,,,{ ,,,,,,,,,,,交换((孩子),,(父母)); ,,,,,,,,,,,parent =,孩子; ,,,,,,,,,,,child =, 2, *, parent +, 1; ,,,,,,,} ,,,,,,, ,,,,,,,{ ,,,,,,,,,,,休息; ,,,,,,,} ,,,} } void 打印(int *,, int 大小) { ,,,cout & lt; & lt;,“升序序列为:“& lt; & lt; endl; ,,,for (int 小姐:=,0;,小姐:& lt;,大小;,我+ +) ,,,{ ,,,,,,,cout & lt; & lt;,一个[我],& lt; & lt;,“,,”; ,,,} ,,,cout & lt; & lt;, endl; } void 堆排序(int *, int 大小) { ,,,维护(一个); ,,,, ,,,//建成最大的堆 ,,,for (int 小姐:=,(size 安康;2),/,2,,小姐:在=0;,我——) ,,,{ ,,,,,,,AdjustDown(我,大小); ,,,} ,,,//交换顺序 ,,,for (int 小姐:=,0;,小姐:& lt;,大小;,我+ +) ,,,{ ,,,,,,,交换(一个[0],[size 安康;小姐:安康;1]); ,,,,,,,AdjustDown (,, 0,, size-i-1); ,,,},,,, } , void 测试() { ,,,int arr[],=,{, 12日,2,,,,4,6,8,54岁,67100年,34678年,25岁,178年,}; ,,,int size =, sizeof (arr),/, sizeof (arr [0]); ,,,堆排序(加勒比海盗,大小),,,,, ,,,印刷(加勒比海盗、大小); } int main () { ,,,()测试; ,,,系统(“暂停”); ,,,return 0; }
时间复杂度:
(n - 2)/2 * lgn + n * (1 + lgn)——→O (n)。