java 小根堆 排序_堆排序 - Java

堆功能有限但被大量使用,常用于快速查找数组中第k个最小/大元素,或按最大/小优先级处理的场景(优先级队列)。

d280162eb196ce97c0cfa90622d9d4e6.png

定义

“堆”不是特指某个数据结构,而是泛指满足堆属性的任何数据结构。

堆中某个子节点的值不大于或不小于父节点的值。

根节点存放最大值的堆叫最大堆/大根堆。

存放最小值的堆叫最小堆/小根堆。

1820e4a9f93fb4daac5842eccd8965d3.png

特点

堆排序的最坏、最好、平均时间复杂度均为O(nlogn),是不稳定排序算法。

注:稳定指,如果a=b,a在b的前面,排序后a仍然在b前面;不稳定指,如果a=b,a在b的前面,排序后位置可能发生交换。

排序算法

利用数组快速定位,指定索引元素基于数组进行堆排序。

dfb6bcdab43d7817ac4f42f691c1205c.png

找出数组中最大元素,根元素array[1]是数组中最大元素。

将该元素与数组中最后一个元素交换(最大堆)。

然后,将数组长度减少1,将已处于正确位置的元素排除在堆外。

重复这个过程,随着下标范围收缩,可遍历数组长度越来越短,直到排序完成。

过程

步骤1:用5替换8。

步骤2:8与堆断开连接,8已处于正确位置。

步骤3:构建大根堆,用3替换7。

步骤4:7与堆断开连接。

第5步:构建大根堆,用1替换5。

步骤6:5与堆断开连接。

步骤7:构建大根堆,用3替换4。

步骤8:4与堆断开连接。

步骤9:构建大根堆,用1替换3。

步骤10:3断开连接。

0bcaec465d4e74fbe389e9fabbb4f18b.png

3d64ca95d9674a3b573e0ff4a5420f2f.png

示例public class HeapSort {

public static void main(String args[]) {

int arr[] = {4, 3, 7, 1, 8, 5};

int n = arr.length;

// 初始化堆

for (int i = n / 2 - 1; i >= 0; i--)

heapify(arr, n, i);

//排序

for (int i = n - 1; i >= 0; i--) {

int temp = arr[0];

arr[0] = arr[i];

arr[i] = temp;

heapify(arr, i, 0);

}

// 打印结果

printArray(arr);

}

static void heapify(int arr[], int n, int i) {

int largest = i; // 初始化根

int l = 2 * i + 1;

int r = 2 * i + 2;

// left > root

if (l < n && arr[l] > arr[largest])

largest = l;

// right > root

if (r < n && arr[r] > arr[largest])

largest = r;

// 如果最大值不是根节点,调整

if (largest != i) {

int swap = arr[i];

arr[i] = arr[largest];

arr[largest] = swap;

// heapify

heapify(arr, n, largest);

}

}

static void printArray(int arr[]) {

int n = arr.length;

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

System.out.print(arr[i] + " ");

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值