完全二叉树
- 对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。
数组转完全二叉树
- 在不越界的情况下,位置i左孩子下标 2*i +1
- 在不越界的情况下,位置i右孩子下标 2*i + 2
- 在不越界的情况下,位置i的父节点(i-1)/2
大根堆
- 在一个树中,任何一个子树的最大值都是这个子树的头部
小根堆
- 在一个树中,任何一个子树的最小值都是这个子树的头部
数组变大根堆
- 首先将数组转化为完全二叉树,将将每一个子节点与父亲节点(i-1)/2相比较,如果比父节点大则与父节点交换
public static void heapSort(int[] arr) {
for (int i = 0; i < arr.length; i++) {
heapInsert(arr,i);
}
}
public static void heapInsert(int[] arr, int index) {
while (arr[index] > arr[(index - 1) / 2]) {
swap(arr,index,(index-1)/2);
index = (index-1)/2;
}
}
public static void swap(int[] arr, int L, int R) {
int t = arr[L];
arr[L] = arr[R];
arr[R] = t;
}
当堆中某个元素发生改变时重新对该元素排序
- 将发生改变的元素与孩子节点的中的最大值相比较,如果小于则交换,直到该元素无法再交换
public static void heapify(int[] arr, int index, int heapSize) {
int leftNode = 2 * index + 1;
while (leftNode < heapSize) {
int largest = leftNode + 1 < heapSize && arr[leftNode + 1] > arr[leftNode] ? leftNode+1 : leftNode ;
largest = arr[largest]>arr[index]?largest:index;
if(largest==index) {
break;
}
swap(arr,largest,index);
index = largest;
leftNode = index *2 +1;
}
}
堆排序算法的实现思路
- 首先将该数组转为一个大根堆(利用上述的heapInsert),将堆顶元素依次与最后一个元素交换,数组长度-1,将最后一个元素隔离,再利用上述的heapify方法对元素进行重新排列二叉树,依次类推,直到数组长度为0
- 时间复杂度:O(n*log n)
public static void heapSort(int[] arr) {
if(arr ==null || arr.length <2) {
return;
}
for (int i = 0; i < arr.length; i++) {
heapInsert(arr, i);
}
int size = arr.length;
swap(arr,0,--size);
while(size>0) {
heapify(arr,0,size);
swap(arr,0,--size);
}
}
public static void heapInsert(int[] arr, int index) {
while (arr[index] > arr[(index - 1) / 2]) {
swap(arr, index, (index - 1) / 2);
index = (index - 1) / 2;
}
}
public static void heapify(int[] arr, int index, int heapSize) {
int leftNode = 2 * index + 1;
while (leftNode < heapSize) {
int largest = leftNode + 1 < heapSize && arr[leftNode + 1] > arr[leftNode] ? leftNode+1 : leftNode;
largest = arr[largest]>arr[index]?largest:index;
if(largest==index) {
break;
}
swap(arr,largest,index);
index = largest;
leftNode = index *2 +1;
}
}
public static void swap(int[] arr, int L, int R) {
int t = arr[L];
arr[L] = arr[R];
arr[R] = t;
}