- !!!排序仅针对于数组哦
- 本次排序是按照升序来的哦
介绍
- 堆排序英文名为Heapsort
- 是一种类似完全二叉树的结构,且满足父节点的值大于子节点的值
完全二叉树、大顶堆、二维数组的关系
-
以下内容的解释均以该数组为例
int[] arr= {5,7,4,2,0,3,1,6};
-
完全二叉树:
- 数据据从上到下,从左到右进行排列。
- 一个节点如果有孩子一定有左孩子
-
完全二叉树与数组
- 父节点:parent;左孩子:lchild;右孩子:rchild; (此处表示在数组中的索引值)
- lchild = 2* parent+1;rchild = 2* parent+2 或 rchild = lchild + 1
-
大顶堆
- 父节点的值大于或等于其左右孩子的值
(下图为构建好的大顶堆)
- 父节点的值大于或等于其左右孩子的值
基本思路
- 一、利用完全二叉树构建大顶堆
- 1、从后往前检测节点是否符合大顶堆的要求
- 2、定义parent、child;parent为当前节点,child为子节点中最大值
(1)父子节点进行比较,父节点大,符合大顶堆,继续向前检查
(2)子节点值大,不符合大顶堆,父子节点交换,parent指向child,child指向其左右孩子最大值,继续判断,直到父节点值大,或者child为空
- 二、堆顶元素和堆底元素进行互换,堆底元素不再参与构建。剩余元素继续构建大顶堆
- 三、重复二
- 看个图换换脑子吧
代码
<!----java代码----->
import java.util.Arrays;
public class HeapSort {
public static void main(String[] args) {
int[] arr= {5,7,4,6,0,3,1,2};
sort(arr);
System.out.println(Arrays.toString(arr));
}
public static void sort(int[] arr) {
if(arr==null||arr.length<2) {
return;
}
// 首次构建时从后往前每个节点均需构建。之后只需维护交换的点即可
for(int p=arr.length-1;p>=0;p--) {
// 首次构建没有不参与的点,所以length不变
adjust(arr, p, arr.length);
}
// 堆顶堆底互换,堆顶固定,堆底变化,所以循环从堆底开始
for(int i=arr.length-1;i>=0;i--) {
// 堆顶和堆底交换
int temp = arr[0];
arr[0] = arr[i];
arr[i]=temp;
// 对堆顶进行维护,有效长度跟着i走
adjust(arr, 0, i);
}
}
// 创建方法,对单个节点进行大顶堆的维护
public static void adjust(int[] arr,int parent,int length) {
/* arr 为需要排序的二维数组
* parent 为需要父节点,也可以理解为当前节点
* length 为构建的长度,因为构建后不需要再参与了,长度会变
* */
// 有孩子一定有左孩子,先定义一个孩子节点
int child = 2*parent +1;
while(child<length) {
// 定义右孩子,判断然后找出最大值,并让child指向最大的
int rchild = child+1;
if(rchild<length && arr[rchild]>arr[child]) {
child++;
}
if(arr[parent]<arr[child]) {
// 父子节点进行比较,如果子节点大,进行交换,然后再循环去检查子节点是否符合大顶堆
int temp = arr[parent];
arr[parent] = arr[child];
arr[child] =temp;
parent = child;
child = 2*child+1;
}else {
// 父节点>子节点,结束循环
break;
}
}
}
}
<!------------------------>
运行结果;
[0, 1, 2, 3, 4, 5, 6, 7]
<!----python代码----->
arr = [5, 7, 4, 6, 0, 3, 1, 2];
def adjust(arr, partent, length):
lchild = 2*partent+1
rchild = lchild+1
while(lchild<length):
if(rchild<length and arr[lchild]<arr[rchild]):
child=rchild
else:
child=lchild
if(arr[partent]<arr[child]):
arr[partent],arr[child] = arr[child],arr[partent]
partent,lchild = child,2*child+1
else:
break
def HeapSort(arr):
if len(arr)<2:
return
for p in range(len(arr)-1,-1,-1):
adjust(arr,p,len(arr)-1)
for i in range(len(arr)-1,-1,-1):
arr[i],arr[0] = arr[0],arr[i]
adjust(arr,0,i)
print(arr)
HeapSort(arr)
<!------------------------>
运行结果;
[0, 1, 2, 3, 4, 5, 6, 7]