欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 资讯 > 排序算法--堆排序

排序算法--堆排序

2024/11/30 0:23:20 来源:https://blog.csdn.net/weixin_40364421/article/details/141655453  浏览:    关键词:排序算法--堆排序

简介

堆排序是一种利用堆数据结构实现的排序算法。首先,它将待排序的数组构建成一个大顶堆或小顶堆。然后,通过不断将堆顶元素(最大或最小)与末尾元素交换并重新调整堆,使得数组逐渐有序。

第一步:构建大顶堆/小顶堆

下面就是一个用大顶堆构建的例子:
在这里插入图片描述
最后要达成的效果就是每个节点的值都大于或等于其左右孩子节点的值,称为大顶堆。

理解了上面的概念后,继续下一步

第二步:将堆顶元素与末尾元素进行交换

交换过程如下:
需要注意的是,每次交换完毕,能保证末尾元素是最大的,但是交换来的数据不一定是当前最大的,所以需要继续将该节点放入合适的位置,再次构建大顶堆
在这里插入图片描述
这样排序就结束了,其实并不复杂。我们只需要完全理解其中的关键点就可以实现:

  • 构建:调整每个节点(非叶子节点)至合适的位置,构建大/小顶堆
  • 交换:交换末尾元素后,继续将该节点调整

实现(java例子)

利用大顶堆和递归的方式,实现排序

	public static void creatBigHeap(int[] a, int len) {// 将无序序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆// len / 2 - 1 很关键, 无需调整叶子节点,对每个非叶子结点进行调整for (int i = len / 2 - 1; i >= 0; i--) {adjustDown(a, i, len);}// 将堆顶元素与末尾元素交换。将最大的元素沉到数组末端for (int j = a.length - 1; j > 0; j--) {swap(a, 0, j);// 重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序adjustDown(a, 0, j);}}/*** 递归调整 (某一个节点至合适的位置)** @param a 数组* @param i 调整的节点* @param length 数字大小*/private static void adjustDown(int[] a, int i, int length) {if (i < length) {int largest = i;// 左子节点, 右子节点int left = i * 2 + 1;int right = i * 2 + 2;if (left < length && a[left] > a[largest]) {largest = left;}if (right < length && a[right] > a[largest]) {largest = right;}// 如果没有放到合适位置,此时需要交换,继续递归if (largest != i) {swap(a, i, largest);// 调整完,继续向下递归调整, 核心点就是将该值放入子树中合适的位置,可以非递归adjustDown(a, largest, length);}}}public static void swap(int[] a, int i, int j) {int temp = a[i];a[i] = a[j];a[j] = temp;}

代码中并没有特别复杂,需要注意细节:

  • i = len / 2 - 1 只调整非叶子结点
  • 只有largest != i 时需要进行递归,说明未到合适的位置

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com