①根据初始数组去构造初始堆(构建一个完全二叉树,保证所有的父结点都比它的孩子结点数值大)。
②每次交换第一个和最后一个元素,输出最后一个元素(最大值),然后把剩下元素重新调整为大根堆。当输出完最后一个元素后,这个数组已经是按照从小到大的顺序排列了。
(2)算法所需要的数据结构?
涉及到二叉堆的数据结构 import java.util.Arrays;
public class HeapSort { public static void main(String[] args) { int[] a={3,6,23,4,3,2,9,10,18,11}; int arrayLength=a.length; //循环建堆 for(int i=0;i<arrayLength-1;i++){ //建堆 buildMaxHeap(a,arrayLength-1-i); //交换堆顶和最后一个元素 swap(a,0,arrayLength-1-i); System.out.println(Arrays.toString(a)); } System.out.println(Arrays.toString(a)); } //对data数组从0到lastIndex建大顶堆 public static void buildMaxHeap(int[] data, int lastIndex){ //从lastIndex处节点(最后一个节点)的父节点开始 for(int i=(lastIndex-1)/2;i>=0;i--){ //k保存正在判断的节点 int k=i; //如果当前k节点的子节点存在 while(k*2+1<=lastIndex){ //k节点的左子节点的索引 int biggerIndex=2*k+1; //如果biggerIndex小于lastIndex,即biggerIndex+1代表的k节点的右子节点存在 if(biggerIndex<lastIndex){ //若果右子节点的值较大 if(data[biggerIndex]<data[biggerIndex+1]){ //biggerIndex总是记录较大子节点的索引 biggerIndex++; } } //如果k节点的值小于其较大的子节点的值 if(data[k]<data[biggerIndex]){ //交换他们 swap(data,k,biggerIndex); //交换后小的值会被换下来,需要将biggerIndex赋予k, //开始while循环的下一次循环,重新保证k节点(被换下来)的值仍然大于其左右子节点的值 k=biggerIndex; }else{ break; } } } } //交换 private static void swap(int[] data, int i, int j) { int tmp=data[i]; data[i]=data[j]; data[j]=tmp; } } |
堆排序多用于实现优先队列。
当排序可能终止,并且需要从已处理的数据选出最大的几个数据时,可以使用堆排序。
2.使用线性数据结构比如数组就可以实现堆排序
3.