package heap;import java.util.Random;publicclassMaxHeap<E extendsComparable<E>>{public Array<E> data;publicMaxHeap(int capacity){
data =newArray<>(capacity);}publicMaxHeap(){
data =newArray<>();}//将任意数组整理成堆的形状publicMaxHeap(E [] arr){
data =newArray<>(arr);for(int i =parent(arr.length-1); i >=0; i--){shifDown(i);}}//返回堆中的元素个数publicintsize(){return data.getSize();}//返回布尔值,表示堆中是否为空publicbooleanisEmpty(){return data.isEmpty();}//返回完全二叉树的数组表示中,一个索引所表示的元素的父亲节点的索引privateintparent(int index){if(index ==0){thrownewIllegalArgumentException("index-0 doesn't have parent");}return(index -1)/2;}//返回完全二叉树的数组表示中,一个索引所表示的元素的左孩子节点的索引privateintleftChild(int index){return index *2+1;}//返回完全二叉树的数组表示中,一个索引所表示的元素的右孩子节点的索引privateintrightChild(int index){return index *2+2;}//向堆中添加元素 ,在数组尾部添加,如果比父节点大,则互换位置,依次类推publicvoidadd(E e){
data.addLast(e);siftUp(data.getSize()-1);}privatevoidsiftUp(int k){while(k >0&& data.get(parent(k)).compareTo(data.get(k))<0){
data.swap(k,parent(k));
k =parent(k);}}//看堆中最大的是谁public E findMax(){if(data.getSize()==0)thrownewIllegalArgumentException("Can not findMax when heap is empty");return data.get(0);}//向堆中取出元素(最大元素)把最后一个元素补充到堆顶,和孩子中最大的元素互换位置public E extractMax(){
E ret =findMax();
data.swap(0, data.getSize()-1);
data.removeLast();shifDown(0);return ret;}privatevoidshifDown(int k){//有左孩子while(leftChild(k)< data.getSize()){int j =leftChild(k);//有右孩子,并且右孩子比左孩子大if(j +1< data.getSize()&& data.get(j +1).compareTo(data.get(j))>0){
j =rightChild(k);//data[j]是leftChild和rightChild中的最大值if(data.get(k).compareTo(data.get(j))>=0)break;
data.swap(k, j);
k = j;}}}//取出堆中最大的元素,并且替换成元素epublic E replace(E e){
E ret =findMax();
data.set(0,e);shifDown(0);return ret;}publicstaticvoidmain(String[] args){int n =100;
MaxHeap<Integer> maxHeap =newMaxHeap<>();
Random random =newRandom();for(int i =0; i < n; i++){
maxHeap.add(random.nextInt(Integer.MAX_VALUE));}int[] arr =newint[n];for(int i =0; i < n; i++){
arr[i]= maxHeap.extractMax();}for(int i =0; i < n; i++){if(arr[i-1]<arr[i])thrownewIllegalArgumentException("Error");}
System.out.println("test MaxHeap completed");}}
package heap;publicclassArray<E>{private E[] data;privateint size;//记录元素个数//构造函数,用户创建数组开辟的空间publicArray(int capacity){// new 一个E类型的数组
data =(E[])newObject[capacity];
size =0;}publicArray(E[] arr){
data =(E[])newObject[arr.length];for(int i =0; i < arr.length; i++){
data[i]= arr[i];}
size = arr.length;}//用户不传参时,默认开辟空间10publicArray(){this(10);}//获取数组中元素个数publicintgetSize(){return size;}//获取空间大小publicintgetCapacity(){return data.length;}//判断数组是否为空publicbooleanisEmpty(){return size ==0;}//在数组最后添加元素2-3publicvoidaddLast(E e){// if (size == data.length)// throw new IllegalArgumentException("Addlast failed.heap.Array is full");// data[size] = e;// size++;add(size,e);}//在首位置添加元素publicvoidaddFirst(E e){add(0,e);}//指定位置添加元素//元素从后往前挪把指定位置空出来publicvoidadd(int index,E e){if(size == data.length){resize(data.length *2);}if(index<0||index>size)thrownewIllegalArgumentException("Add failed.Require index>=0 and index<=size");for(int i=size-1;i>=index;i--){
data[i+1]=data[i];}
data[index]=e;
size++;}privatevoidresize(int capacity){
E[] newData =(E[])newObject[capacity];for(int i =0; i < size; i++){
newData[i]= data[i];}
data=newData;}//获取index索引的位置public E get(int index){if(index<0||index>=size)thrownewIllegalArgumentException("Add failed.Require index>=0 and index<=size");return data[index];}public E getLast(){returnget(size-1);}public E getFirst(){returnget(0);}//更新数组元素publicvoidset(int index,E e){if(index<0||index>=size)thrownewIllegalArgumentException("Add failed.Require index>=0 and index<=size");
data[index]=e;}//是否包含某元素publicbooleancontains(E e){for(int i =0; i < size; i++){if(e.equals(data[i]))returntrue;}returnfalse;}//返回所要查找的元素的索引publicintfind(E e){for(int i =0; i < size; i++){if(e.equals(data[i]))return i;}return-1;}//删除索引处的某个元素并返回,将索引之后的元素向前移动public E remove(int index){if(index<0||index>size)thrownewIllegalArgumentException("Add failed.Require index>=0 and index<=size");
E result=data[index];for(int i = index+1; i < size; i++){
data[i-1]=data[i];}
size--;if(size==data.length/4&&data.length/2!=0){resize(data.length/2);}return result;}//删除头元素public E removeFirst(){returnremove(0);}//删除最后一个元素public E removeLast(){returnremove(size-1);}//删除某个元素publicvoidremoveElement(E e){int index =find(e);if(index!=-1)remove(index);}//交换元素publicvoidswap(int i,int j){if(i<0||i>=size||j<0||j>=size){thrownewIllegalArgumentException("Index is illegal");}
E t =data[i];
data[i]= data[j];
data[j]= t;}@Overridepublic String toString(){
StringBuilder stringBuilder =newStringBuilder();
stringBuilder.append(String.format("heap.Array:size=%d,capacity =%d\n",size,data.length));
stringBuilder.append("[");for(int i=0;i<size;i++){
stringBuilder.append(data[i]);if(i!=size-1)
stringBuilder.append(",");}
stringBuilder.append("]");return stringBuilder.toString();}}