堆排序
本文主要通过实现一个小根堆排序对堆排序进行一个说明。
堆排序具体分为以下几个函数进行实现:
- heapify(int[] nums, int n, int len)
- heapInitial(int[] nums, int n)
- heapSort(int[] nums)
heapify(int[] nums,int n, int len);
这个函数是堆排序的核心函数,其表示对n为下标的节点进行下筛操作。
- 在n代表的节点、左孩子和右孩子三个节点中找到一个最小的节点
- 将最小的节点交换到n的位置处(父节点处)
- 如果n节点本身就是三个节点中最小的节点,那么不需要继续操作
- 如果进行了节点交换,那么对换下来的节点递归进行heapify
具体实现也不难,需要多注意节点越界即可。
public void heapify(int[] nums,int n, int len) {
/**
* heapify操作
* nums表示当前堆
* n:对下标为n的节点做heapify操作
* len:堆中元素的个数
*/
if(n>=len) return;
//找到两个孩子节点
int c1 = n*2 + 1;
int c2 = n*2 + 2;
//找到最小的元素并且换到堆顶
int min = n;
//注意孩子节点的下标不要越界
if((c1 < len) && (nums[c1] < nums[min])) {
min = c1;
//System.out.println(nums[0]);
}
if((c2 < len) && (nums[c2] < nums[min])) {
min = c2;
//System.out.println(nums[0]);
}
//换好元素之后,再对被换下来的位置进行heapify,
//一直递归往下,直到遇到一个符合小顶堆的子树为止
if(min != n) {
swap(nums,min,n);
heapify(nums, min, len);
}
}
heapInitial(int[] nums, int n);
由于初始数组处于乱序的状态,所以需要对其进行初始化,先建立一个小根堆。我们只需要从最后一个非叶节点,自底向上一次进行heapify即可建立一个小根堆。
public void heapInitial(int[] nums,int n) {
/**
* 对乱序的数组进行堆的创建:
* 从最后一个非叶节点开始,
* 从下往上对每个节点都进行一次heapify
*/
//最后一个非叶节点既是最后一个节点的父亲节点
int parent = (n-1)/2;
for(int i=parent;i>=0;i--)
heapify(nums, i, n);