Heap类实现与排序

堆排序使用的是二叉堆,它是一棵完全二叉树。

堆(Heap)是一棵有以下属性的二叉树:

1.它是一棵完全二叉树

2.每个节点大于或等于任意一个孩子

/*实现Heap类*/
public class Heap<E extends Comparable>{
	private java.util.ArrayList<E> list=new java.util.ArrayList<E>();//用数组线性表表示堆
	public Heap(){//创建一个默认的空堆
	}
	public Heap(E[] objects){//创建一个带指定对象的堆
		for(int i=0;i<objects.length;i++)
			add(objects[i]);	
	}
	public void add(E newObject){//给堆添加一个新对象
		list.add(newObject);
		int currentIndex=list.size()-1;//最后节点索引
		while(currentIndex>0){
			int parentIndex=(currentIndex-1)/2;
			if(list.get(currentIndex).compareTo(list.get(parentIndex))>0){//当前结点大于父结点,交换
				E temp=list.get(currentIndex);
				list.set(currentIndex, list.get(parentIndex));
				list.set(parentIndex, temp);
			}
			else
				break;
			currentIndex=parentIndex;
		}
	}
	public E remove(){//从堆中删除并返回根节点
		if(list.size()==0) return null;
		E removedObject=list.get(0);//取跟结点
		list.set(0, list.get(list.size()-1));//最后结点移到根结点
		list.remove(list.size()-1);//删除最后结点
		int currentIndex=0;//设一个当前指针
		while(currentIndex<list.size()){
			int leftChildIndex=2*currentIndex+1;
			int rightChildIndex=2*currentIndex+2;
			if(leftChildIndex>=list.size())break;
			int maxIndex=leftChildIndex;//一直指向左右孩子中大的那个
			if(rightChildIndex<list.size()){
				if(list.get(maxIndex).compareTo(list.get(rightChildIndex))<0)
					maxIndex=rightChildIndex;
			}
			if(list.get(currentIndex).compareTo(list.get(maxIndex))<0){//父结点小于子结点,交换
				E temp=list.get(maxIndex);
				list.set(maxIndex, list.get(currentIndex));
				list.set(currentIndex, temp);
				currentIndex=maxIndex;
				}
			else
				break;
		}
		return removedObject;
		
	}
	public int getSize(){//返回堆的大小
		return list.size();
	}
}
/*堆排序*/
import java.util.*;
public class HeapSort {
	public static <E extends Comparable> void heapSort(E[] list){
		Heap<E> heap=new Heap<E>();//建立一个堆
		for(int i=0;i<list.length;i++){
			heap.add(list[i]);//往堆中添加元素
		}
		for(int i=list.length-1;i>=0;i--){
			list[i]=heap.remove();//从堆中删除元素
		}
	}
	public static void main(String[] args) {
		Integer[] list={2,3,2,5,6,1,-2,3,14,12};
		heapSort(list);
		for(int i=0;i<list.length;i++)
			System.out.print(list[i]+" ");
	}
}
由于add方法会追踪从叶结点到根结点的路径,因此,添加一个新元素最多需要h步,即建立包含n个元素的初始堆,需要O(nlogn)时间。remove追踪从根结点到叶结点,需要时间同为O(nlogn)。时间效率与归并排序相同,空间效率高于归并排序。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值