堆: 堆逻辑上是一棵完全二叉树, 堆物理上是保存在数组中。满足任意结点的值都大于其子树中结点的值,叫做大堆,或者大根堆,或者最大堆。反之,则是小堆,或者小根堆,或者最小堆。 向下调整,向上调整,建堆,代码实现
public class lx { public static void adjustDown(int []array ,int size,int index){ while (true){ //左孩子的位置为index位置*2+1 int leftChild=2*index+1; //判断是否为叶子节点 出口一 if(leftChild>=size){ return; } //找最小孩子 int rightChild=leftChild+1; int minChild=leftChild; //比较左右孩子的元素大小 小的放进minChild中 if(rightChild<size&&array[rightChild]<array[leftChild]){ minChild=rightChild; } //比较最小孩子(minChild)与index位置的值 if (array[index] <= array[minChild]) { return; } // 4.程序 走到这说明不满足堆的性质 进行交换将index位置元素与minIndex位置的元素进行交换 int t = array[index]; array[index] = array[minChild]; array[minChild] = t; // 5.循环 把最小的孩子视为 index,继续循环直到index位置满足堆的性质 index = minChild; } } public static void adjustUp(int []array ,int size ,int index){ while (true){ // 出口 index位置为根位置 if(index==0){ break; } //找到Index位置的父亲位置 parentIndex int parentIndex=(index-1)/2; //出口 满足堆的性质 父亲的值小于左右孩子 if(array[parentIndex]<array[index]){ break; } // 不满足 交换index位置与parentIndex位置上的元素 int t=array[parentIndex]; array[parentIndex]=array[index]; array[index]=t; } } public static void createHeap(int []array, int size){ //找到层序遍历最后一个结点的下标 int lastIndex=size-1; //找到最后一个结点父节点下标 int parentIndex=lastIndex-1/2; for (int i = parentIndex; i >=0; i--) { adjustDown(array,size,i); } } }我自己实现的优先级队列(堆)add()remove() element() 方法 (以小堆为例) 需要注意的是:当进行add时要进行向上调整(adjust up)当进行remove时要删除优先级队列中第一个元素 并且把最后一个元素放到第一个元素上,然后在进行向下调整(adjust down)
优先级队列(堆):可以找出数组中最大值(大堆),最小值(小堆)
public class MyPriorityQueue { private Integer[] array; private int size; public MyPriorityQueue(){ array=new Integer[100]; size=0; } public Integer element(){ if(size==0){ throw new RuntimeException("空了"); } return array[0]; } public Integer remove(){ if(size==0){ throw new RuntimeException("空了"); } int e=array[0]; array[0]=array[size-1]; size--; adjustDown(0); return e; } public void add(Integer e){ array[size]=e; size++; adjustUp(size-1); } private void adjustDown(int index) { while (true) { int leftChildIndex = 2 * index + 1; if (leftChildIndex >= size) { return; } int rightChildIndex = leftChildIndex + 1; int minChildIndex = leftChildIndex; if (rightChildIndex < size && array[rightChildIndex] < array[leftChildIndex]) { minChildIndex = rightChildIndex; } if (array[index] <= array[minChildIndex]) { return; } int t = array[minChildIndex]; array[minChildIndex] = array[index]; array[index] = t; index = minChildIndex; } } private void adjustUp(int index){ while (true){ if(index==0){ return; } //找到Index位置的父亲位置 parentIndex int parentIndex=(index-1)/2; //出口 满足堆的性质 父亲的值小于左右孩子 if(array[parentIndex]<array[index]){ break; } // 不满足 交换index位置与parentIndex位置上的元素 int t=array[parentIndex]; array[parentIndex]=array[index]; array[index]=t; } } }