Java-最大堆的排序,插入,删除

来源:互联网 发布:城市地图制作软件 编辑:程序博客网 时间:2024/05/21 16:22

先贴一下代码,具体分析以后再说

import java.util.ArrayList;import java.util.Collections;import java.util.Scanner;public class Main {public static void main(String[] args){Scanner in = new Scanner(System.in);int len = in.nextInt();ArrayList<Integer> maxHeap = new ArrayList<Integer>();// 初始的数据int value = 0;maxHeap.add(0);     // 下标为0的位置不存放数字,从1开始存放for(int i=1;i<=len;i++){value = in.nextInt();maxHeap.add(value);}// 过程1(调整法):调整使其成为一个大顶堆,从最后一个非叶节点开始调整for(int i=(maxHeap.size()-1)/2;i>=1;i--){   // 注意边界adjustHeap(maxHeap,i,maxHeap.size());}// 输出大顶堆System.out.print("大顶堆为:");for(int i=1;i<maxHeap.size();i++){          // 注意边界System.out.print(maxHeap.get(i)+" ");}// 过程2:在大顶堆中插入数字insert(maxHeap,10);System.out.print("插入数字后大顶堆为:");for(int i=1;i<maxHeap.size();i++){          // 注意边界System.out.print(maxHeap.get(i)+" ");}// 过程3:从大顶堆中删除数字delete(maxHeap,2);System.out.print("删除数字后大顶堆为:");for(int i=1;i<maxHeap.size();i++){          // 注意边界System.out.print(maxHeap.get(i)+" ");}// 过程4:对大顶堆进行排序sort(maxHeap);System.out.print("排序后数组:");for(int i=1;i<maxHeap.size();i++){          // 注意边界System.out.print(maxHeap.get(i)+" ");}}public static int left(int index){               // 注意边界return 2*index;}public static int right(int index){return 2*index+1;}//过程1: 调整堆,对堆中某个元素进行调整public static void adjustHeap(ArrayList<Integer> maxHeap,int i,int size){// 注意,从数组下标为1的开始int index = i;int lchild = left(i);int rchild = right(i);if(index<=(size-1)/2){ // 确保不是叶子节点if(lchild<=size&&maxHeap.get(index)<maxHeap.get(lchild))index = lchild;if(rchild<size&&maxHeap.get(index)<maxHeap.get(rchild))index = rchild;    // index此时为两个子节点中较大的值if(i!=index){Collections.swap(maxHeap,i,index);adjustHeap(maxHeap,index,size);   // 以index为根的子树往下继续调整}}}//过程2: 向最大堆中插入数据public static void insert(ArrayList<Integer> maxHeap,int value){// 在数组尾部添加,且注意下标为0的位置不放元素if(maxHeap.size()==0)maxHeap.add(0);maxHeap.add(value);heapUp(maxHeap,maxHeap.size()-1);}//过程2:把"插入"的元素上浮public static void heapUp(ArrayList<Integer> maxHeap,int index){if(index>1){// 求出其父亲节点int parent = index/2;int parentValue = maxHeap.get(parent);int indexValue = maxHeap.get(index);// 如果父亲节点的值小于index节点的值,交换两者的位置if(parentValue<indexValue){Collections.swap(maxHeap, parent, index);heapUp(maxHeap,parent);}}}//过程3:把最大堆中的某个元素删除public static void delete(ArrayList<Integer> maxHeap,int index){// 把最后的一个叶子的数值赋值给index位置maxHeap.set(index,maxHeap.get(maxHeap.size()-1));// 下沉操作heapDown(maxHeap,index);maxHeap.remove(maxHeap.size()-1);   // 移除}    //过程3:"下沉"操作public static void heapDown(ArrayList<Integer> maxHeap,int index){// 因为第一个位置存储的是控制,不考虑在内,最后一个也要删除,不考虑在内int n = maxHeap.size()-2;// 记录较大的儿子的位置int child = -1;if(2*index>n){       // 2*index>n 说明该节点没有左右儿子节点了,则返回return;}else if(2*index<n){ // 两个儿子都在child = 2*index;if(maxHeap.get(child)<maxHeap.get(child+1)){child++;}}else if(2*index==n){  // 只有左儿子child=2*index;}// 交换和递归if(maxHeap.get(child)>maxHeap.get(index)){Collections.swap(maxHeap, child, index);heapDown(maxHeap,child);}}//程序4:对大顶堆进行排序public static void sort(ArrayList<Integer> maxHeap){for(int i=maxHeap.size()-1;i>0;i--){Collections.swap(maxHeap, 1, i);adjustHeap(maxHeap,1,i);}}}


原创粉丝点击