java实现排序算法之堆排序

news/2024/5/19 4:06:27 标签: 堆排序, java实现

首先说一下堆的概念,堆分小顶堆和大顶堆。

小顶堆,堆顶元素小于左子树及右子树上边的值,同时左右子树也是小顶堆,这样类推下去。同理大顶堆,就是堆顶元素大于左右子树所有元素,左右子树也分别是大顶堆。


下边开始算法解释

排序时每次将堆顶元素取走,将最后一个元素放在第一个元素的位置上,然后将剩下的i-1个元素重新调整为堆,依次类推。及排序过程就是不断的调整堆的过程。

我们讨论顺序排序,数组a[0-n-1],i 做循环元素,从n-1开始,将0~i元素调整为大顶堆,然后将第0个元素和第i个元素交换。然后再对i-1个元素作堆调整,依次类推知道数组排序完成。

将一维数组中的树看成一个完全二叉树(完全二叉树除了叶子节点以外,所有节点都有左右两个孩子节点,具体概念可百度),即例如一组数:{49,38,65,97,76,13,27,49}

看成二叉树形式:


首先将其调整成大顶堆(由于完全二叉树的最后一个非叶子节点元素为 n/2(,完全二叉树的性质,可先行理解完全二叉树)故从下标n/2开始调整到下标0)调整过程:

1.由于49小于97,故不需要调整

2.由于65大于13和27故不需要调整

3.由于38小于97个76,且97大于76,故将97和和38交换


由于交换后38小于49,故需要交换

    

4.由于49小于左右子树,故将左右子树中偏大者即97与49交换

交换完之后,49小于76,故将76余49交换


至此,一个又鲜又嫩的大顶堆调整好了。

然后将97移除,即在数组中放在最后一个位置(不再参与堆调整),然后将38调整到第一位


同理进行类似的堆调整,然后将堆顶元素移除(即在数组中方在倒数第二个位置,不再参与堆调整),将最后一个元素放在第一个元素,然后进行堆调整。依次类推

直到所有的元素调整好。

代码如下

package heap;
import java.util.Arrays;
public class HeapSort {
public static void main(String[] args) {
int[] a = new int[] { 33, 9, 34, 12, 6, 10, 8, 9, 32, 1 };
int[] b = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
HeapSort heapSort = new HeapSort();
heapSort.heapSort(a);
heapSort.heapSort(b);
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(b));
}
public void heapAdjust(int[] a, int s, int e) {
int rc = a[s];//记录堆顶元素的值,然后将其与左右子树的值进行比较
//将较大者网上填,最后找到适合rc的位置填入其中,由于数组下标从0开始,故其左子树为2*s+1而不是2*s
for (int i = 2 * s + 1; i <= e; i = 2 * i + 1) {
if (i < e && a[i + 1] > a[i])
i++;//找出左右孩子中较大者
if (rc > a[i])
break;//比较较大者与待调整元素的大小
a[s] = a[i];//将较大者赋值为父节点
s = i;//记录rc需要填写的位置
}
a[s] = rc;//元素归为
}
public void heapSort(int[] a) {
int length = a.length;
int tmp;
int i;
for (i = length / 2 - 1; i >= 0; i--) {
heapAdjust(a, i, length - 1);//从n/2个元素开始调整,直到第一个元素,调整为一个大顶堆
}
for (i = length - 1; i > 0; i--) {
tmp = a[i];//
a[i] = a[0];//将堆顶元素与最后一个元素交换,即移除堆顶元素,将最后一个元素放在第一个元素
a[0] = tmp;
heapAdjust(a, 0, i - 1);//调整前i-1个元素为大顶堆,i元素不再参与堆调整
}
}
}


http://www.niftyadmin.cn/n/789807.html

相关文章

排序算法之2路归并排序(递归和非递归)

归并排序&#xff0c;从字面意思上理解&#xff0c;即合并的时候排序。 归并排序是分治法的一种&#xff0c;首先将待排数列分成1个一个元素&#xff0c;然后依次按大小合并。 排序过程 分 初始关键值 [49] [38] [65] [97] [76] [13] [27] 合 …

msxml 操作xml

1.简介 在.NET平台&#xff0c;微软为C#或托管C程序员提供了丰富的类库&#xff0c;用以支持各种需求&#xff0c;其中就有对XML文件操作的丰富的类。例如XMLDocument, XmlElement等。但是C标准库中并未提供相应的库。本地开发的C程序员一般采用开源类库实现对XML文件的操作&am…

团队冲刺-3

注&#xff1a;补齐5.12的博文 今天做了什么 我们先是在晚上7:30-8:30召开了我们的第一次回顾会议总结了一下自己。在会议结束后我回宿舍继续观看视频资料&#xff0c;并按照视频上的例子自己敲写。 明天做什么&#xff1a; 明天课程比较少&#xff0c;计划初步构建数据库&…

认识HTML5的WebSocket

记录一下&#xff0c;以便查找在HTML5规范中&#xff0c;我最喜欢的Web技术就是正迅速变得流行的WebSocket API。WebSocket提供了一个受欢迎的技术&#xff0c;以替代我们过去几年一直在用的Ajax技术。这个新的API提供了一个方法&#xff0c;从客户端使用简单的语法有效地推动消…

“服务器推”技术的应用

请访问 Ajax 技术资源中心&#xff0c;这是有关 Ajax 编程模型信息的一站式中心&#xff0c;包括很多文档、教程、论坛、blog、wiki 和新闻。任何 Ajax 的新信息都能在这里找到。 centertop 订阅 Ajax 相关文章和教程的 RSS 提要 传统模式的 Web 系统以客户端发出请求、服务器…

Java 组合的实现- 输入一个字符,输出字符中字母组成的所有组合

今天遇到的笔试题&#xff0c;时间紧张没有想出来。笔试完后总结一下解决方法。 题目如下&#xff1a; 给出一个字符串例如&#xff1a;”abc“&#xff0c;输出组成该字符的字母组成的所有组合。上例&#xff1a;a,b,c,ab,ac,bc,abc&#xff1b; 以abcde为例来解释&#xf…

java中几个时间的区别(java.sql.date,java.sql.time,java.sql.Timestamp)

java.util.Date、java.sql.Date、java.sql.Time、java.sql.Timestamp、以及与MySQL日期类型的对应 一、java.util.Date表示某一特定时刻&#xff0c;精确到毫秒。 java.util.Date日期格式为&#xff1a;年月日时分秒 类声明如下&#xff1a; public class Date imple…

UUID的解释

UUID的解释UUID是指在一台机器上生成的数字&#xff0c;它保证对在同一时空中的所有机器都是唯一的。通常平台会提供生成的API。按照开放软件基金会(OSF)制定的标准计算&#xff0c;用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字UUID由以下几部分的组合&#xff1…