0位置做头节点,i位置左孩子的下标:2i+1;右孩子下标:2i+2;父节点下标:(i-1)/2。
1.大顶堆构建思想
构建大顶堆,每到一个数字,与其父节点进行比较,若大于父节点,则与父节点交换,然后接着向上比较,直到不符合条件或者到达根节点停止。
1.1一个大根堆,要求删除顶点后,将其再调整为大根堆。
思路:(1)将最后一个数,也就是heapsize位置的数放置在根节点,然后heapsize--。
(2)将此数与左右两孩子中较大的那个进行比较,若小于就交换,若大于等于或者没有孩子了,算法停止。注意:如果右孩子的索引位置>heapsize,表明右孩子不存在,直接与左孩子进行比较即可。
(3)重复步骤(2)。
2.堆排序
2.1思想
(1)构建大根堆
(2)根节点与最后位置交换,heapsize--
(3)只要heapsize>0,heapify,转步骤(2).
2.2代码实现
public class Test { public static void main(String[] args) { int[] arr = {26,87,34,65,2}; heapSort(arr); for (int i = 0; i <arr.length; i++) System.out.print(arr[i]+" "); } public static void heapSort(int[] arr){ if(arr==null || arr.length<2) return; //1.构建大顶堆 for (int i = 1; i <arr.length; i++) { heapInsert(arr,i); } //2.调整 int heapsize = arr.length; swap(arr,0, --heapsize); while (heapsize>0){ heapify(arr, 0,heapsize); swap(arr,0, --heapsize); } } //新的根节点下沉 public static void heapify(int[] arr, int index,int heapsize){ int left = index*2+1; while (left<heapsize){ int largest = left+1<heapsize&&arr[left+1]>arr[left]? left+1:left; //找出左右孩子较大的一个的位置, // 前提是右孩子小于heapsize largest = arr[largest]>arr[index]?largest:index; if(largest==index||largest==heapsize) break; swap(arr,index,largest); index = largest; left = index*2+1; } } //数字大于父节点就交换 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; if(index<=0) break;//比较到根节点 } } public static void swap(int[] arr, int x, int y){ int tmp = arr[x]; arr[x] = arr[y]; arr[y] = tmp; } }