大顶堆:在完全二叉树的基础上,每个结点的值都大于或等于其左右孩子结点的值
p在主函数中通过循环p-- 指针向前走
public static void main(String[] args) {
int[] arr = {8,7,3,5,4,9,1,3};
for (int p = arr.length-1;p>=0;p--){
adjustHeap(arr,p,arr.length);
}
}
在第5次循环的时候 终于找到了儿子节点
但此时temp=5 >3,不满足交换的条件,所以继续往前走
此时 temp=3 <5(其左子节点),所以进行交换
此时变成了
public static void adjustHeap(int[] arr,int parent,int length){
// 定义一下父节点的值
int temp = arr[parent];
//定义左孩子
int lChild = 2 * parent +1;
//循环是为了检查交换后的儿子节点有没有儿子节点,如果有再次比较大小
while (lChild <length){
// 定义右孩子
int rChild = lChild + 1;
// 找打左右孩子当中最大的是谁
if (rChild <length && arr[lChild] <arr[rChild]){
lChild++;
}
if (temp >= arr[lChild]){
break;
}
// 把子节点的值赋值到父节点的位置
arr[parent] = arr[lChild];
parent = lChild;
lChild = 2 * lChild+1;
}
arr[parent] = temp;
}
其中 while循环是为了检查交换后的儿子节点有没有儿子节点,如果有再次比较大小
while (lChild <length){
// 定义右孩子
int rChild = lChild + 1;
// 找打左右孩子当中最大的是谁
if (rChild <length && arr[lChild] <arr[rChild]){
lChild++;
}
if (temp >= arr[lChild]){
break;
}
// 把子节点的值赋值到父节点的位置
arr[parent] = arr[lChild];
parent = lChild;
lChild = 2 * lChild+1;
}
此时parent的指针指到了其子节点上面,其子节点的的指针指到了变换之后子节点的子节点上面
这个时候由于变换之后的parent上没有子节点
所以 不满足
while (lChild <length)
的循环条件,所以结束while循环
执行
arr[parent] = temp;
这一步的完成标志着 交换完成
结束此次for循环
继续执行for循环
依然是父节点上的值比子节点大,不进行交换,继续向前走
此时一个大顶堆产生,最大的值产生了出来
要进行堆排序,需要产生数组长度个大顶堆
public class HeapSort {
public static void main(String[] args) {
int[] arr = {8,7,3,5,4,9,1,3};
int l=arr.length;
int[] sort =new int[arr.length];
for(int i=sort.length-1;i>=0;i--) {
for (int p = l-1;p>=0;p--){
adjustHeap(arr,p,l);
}
sort[i]=arr[0];
arr[0]=arr[l-1];
l--;
}
System.out.println(Arrays.toString(sort));
}
在原来产生大顶堆的for循环外面再套一层for循环
内部的for循环完毕产生一个大顶堆,也就是一个当前最大值,将这个最大值放在新数组的最后一位
sort[i]=arr[0];
并将arr数组的首位拿掉,将末位放在首位,也就意味之数组长度减一
arr[0]=arr[l-1];
l--;
通过两层循环,得到了一个从大到小排序的数组
这就是堆排序
源代码部分:
import java.util.Arrays;
public class HeapSort {
public static void main(String[] args) {
int[] arr = {8,7,3,5,4,9,1,3};
int l=arr.length;
int[] sort =new int[arr.length];
for(int i=sort.length-1;i>=0;i--) {
for (int p = l-1;p>=0;p--){
adjustHeap(arr,p,l);
}
sort[i]=arr[0];
arr[0]=arr[l-1];
l--;
}
System.out.println(Arrays.toString(sort));
}
public static void adjustHeap(int[] arr,int parent,int length){
// 定义一下父节点的值
int temp = arr[parent];
//定义左孩子
int lChild = 2 * parent +1;
//循环是为了检查交换后的儿子节点有没有儿子节点,如果有再次比较大小
while (lChild <length){
// 定义右孩子
int rChild = lChild + 1;
// 找打左右孩子当中最大的是谁
if (rChild <length && arr[lChild] <arr[rChild]){
lChild++;
}
if (temp >= arr[lChild]){
break;
}
// 把子节点的值赋值到父节点的位置
arr[parent] = arr[lChild];
parent = lChild;
lChild = 2 * lChild+1;
}
arr[parent] = temp;
}
}