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

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

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);
		}
	}

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值