文章目录
- 把普通数组转换大顶堆数组
- 堆增删改查替换
- 堆排序
把普通数组转换大顶堆数组
该方式适用索引为0起点的堆
在堆(Heap)这种数据结构中,节点被分为两类:叶子节点(Leaf Nodes)和非叶子节点(Non-Leaf Nodes)。
叶子节点是指没有子节点的节点,它们位于堆的最底层。在堆中,叶子节点的数量总是大于或等于非叶子节点的数量。
非叶子节点是指至少有一个子节点的节点,它们位于堆的上层。在二叉堆(Binary Heap)中,非叶子节点的数量总是等于总节点数的一半(向上取整)。
在堆的操作中,非叶子节点的重要性体现在维护堆的性质(如最大堆或最小堆)方面。当插入或删除节点时,可能需要对非叶子节点进行调整,以确保堆的性质得到维护。
package Heap;import java.util.Arrays;//大顶堆
public class MaxHeap {int [] array;int size;public MaxHeap(int capacity){this.array=new int[capacity];}public MaxHeap(int [] array){this.array=array;this.size=array.length;heapify();}//建堆private void heapify(){
// size/2-1找到非叶子节点for (int i=size/2-1;i>=0;i--){down(i);}}//将 parent 索引处的元素下潜:与两个孩子较大者交换,直至没孩子//或者孩子没他大private void down(int parent){int left = parent*2+1;int right=left+1;int max = parent;if (left<size && array[left]> array[max]){max=left;}if (left<size && array[right]> array[max]){max=right;}if (max!=parent){//找到了更大的孩子swap(max,parent);down(max);}}//交换两个索引private void swap(int i,int j){int t = array[i];array[i]=array[j];array[j]=t;}public static void main(String[] args) {int [] arr= {1,2,3,4,5,6,7};MaxHeap maxHeap = new MaxHeap(arr);System.out.println(Arrays.toString(maxHeap.array));}
}
堆增删改查替换
package Heap;import java.util.Arrays;// 大顶堆
public class MaxHeap {int[] array;int size;public MaxHeap(int capacity) {this.array = new int[capacity];}public MaxHeap(int[] array) {this.array = array;this.size = array.length;heapify();}// 获取堆顶元素public int peek() {return array[0];}// 删除堆顶元素public int poll() {int top = array[0];swap(0, size - 1);size--;down(0);return top;}// 删除指定索引public int poll(int index) {int delete = array[index];swap(index, size - 1);size--;// 维护堆的性质if (index > 0 && array[index] > array[(index - 1) / 2]) {up(index);} else {down(index);}return delete;}// 替换指定索引的元素public void replace(int index, int value) {int oldValue = array[index];array[index] = value;// 维护堆的性质if (value > oldValue) {up(index);} else {down(index);}}// 在堆尾部添加元素public void add(int value) {array[size] = value;size++;up(size - 1);}// 建堆private void heapify() {// size/2-1找到非叶子节点for (int i = size / 2 - 1; i >= 0; i--) {down(i);}}// 将 parent 索引处的元素下沉:与两个孩子较大者交换,直至没孩子// 或者孩子没他大private void down(int parent) {int left = parent * 2 + 1;int right = left + 1;int max = parent;if (left< size && array[left] > array[max]) {max = left;}if (right< size && array[right] > array[max]) {max = right;}if (max != parent) { // 找到了更大的孩子swap(max, parent);down(max);}}// 将 child 索引处的元素上浮:与父节点比较,直至父节点大于等于它private void up(int child) {int parent = (child - 1) / 2;while (child > 0 && array[child] > array[parent]) {swap(child, parent);child = parent;parent = (child - 1) / 2;}}// 交换两个索引private void swap(int i, int j) {int t = array[i];array[i] = array[j];array[j] = t;}public static void main(String[] args) {int[] arr = {1, 2, 3, 4, 5, 6, 7};MaxHeap maxHeap = new MaxHeap(arr);System.out.println(Arrays.toString(maxHeap.array));maxHeap.add(8);System.out.println(Arrays.toString(maxHeap.array));maxHeap.replace(3, 9);System.out.println(Arrays.toString(maxHeap.array));maxHeap.poll(2);System.out.println(Arrays.toString(maxHeap.array));}
}
堆排序