堆的基本储存

1.堆的基本储存

package maxHeap/*
* 堆定义
*/
public class MaxHeap<T> {
	private T[] data;
	private int count;
	//构造函数,构造一个空堆,可容纳capacity个元素
	public MaxHeap(int capacity) {
		data = (T[])new Object[capacity + 1];
		count = 0;
	}
	// 返回堆中的元素个数
	public int size() {
		return count;
	}
	//返回一个布尔值,表示堆中是否为空
	public boolean isEmpty(){
		return count == 0;
	}
	// 测试MaxHeap
	public static void main(String[] args) {
		MaxHeap<Integer> maxHeap = new MaxHeap<Integer>(100);
		System.out.println(maxHeap.size());
	}
}

2.堆的 shift up

package heapShiftUp<T extends Comparable> {
	protected T[] data;
	protected int count;
	protected int capacity;	

	// 构造函数, 构造一个空堆, 可容纳capacity个元素
	public HeapShiftUp(int capacity) {
		data = (T[]) new Comparable[capacity + 1];
		count = 0;
		this.capacity = capacity;
	}

	// 返回堆中的元素个数
	public int size(){
		return count;
	}
	
	//返回堆中的元素个数
	public int size(){
		return count;
	}

	//返回一个布尔值,表示堆中是否为空
	public boolean isEmpty(){
		return count == 0;
	}

	// 向最大堆中插入一个新的元素 item
	public void insert(T item){
		assert count + 1 <= capacity;
		data[count + 1] = item;
		count ++;
		shiftUp(count);
	}

	// 交换堆中索引为i和j的两个元素
	private void swap(int i, int j) {
		T t = data[i];
		data[i] = data[j];
		data[j] = t;
	}

	// 最大堆核心辅助函数
	private void shiftUp(int k) {
		while(k > 1 && data[k/2].compareTo(data[k]) < 0) {
			swap(k, k/2);
			k /= 2;
		}
	}

	// 测试 HeapShiftUp
	public static void main(String[] args) {
		HeapShiftUp<Integer> heapShiftUp = new HeapShiftUp<Integer>(100);
		int N = 50;
		int M = 100;
		for ( int i = 0; i < N ; i ++ )
			heapShiftUp.insert( new Integer((int)(Math.random() * M)) );
		System.out.println(heapShiftUp.size());
	}

}

3.堆的shift down

package heapShiftDown;
/**
* 往最大堆中取出一个元素
*/
public class HeapShiftDown<T extends Comparable> {
	protected T[] data;
	protected int count;
	protected int capacity;

	//构造函数,构造一个空堆,可容纳capacity个元素
	public HeapShiftDown(int capacity){
		//这里加1是指原来能装的元素个数,那去掉0位,只能装capacity个元素
		data = (T[]) new Comparable[capacity + 1];
		count = 0;
		this.capacity = capacity;
	}
	// 返回堆中的元素个数
	public int size() {
		return count;
	}
	//返回一个布尔值,表示堆中是否为空
	public boolean isEmpty() {
		return count == 0;
	}
	// 向最大堆中插入一个新的元素 item
	public void insert(T item){
		
		assert count + 1 <= capacity;
		data[count + 1] = item;
		count ++;
		shiftUp(count);
	}
	// 从最大堆中取出堆顶元素,即堆中所储存的最大数据
	public T extractMax() {
		assert count > 0;
		T ret = data[1];
		swap( 1 , count );
		count -- ;
		shiftDown(1);
		return ret;
	}
	// 获取最大堆中的堆顶元素
	public T getMax() {
		assert( count > 0 );
		return data[1];
	}

	// 交换堆中索引为 i 和 j 的两个元素
	private void swap(int i, int j) {
		T t = data[i];
		data[i] = data[j];
		data[j] = t;
	}
	//最大堆核心辅助函数
	private void shiftUp(int k) {
		while( k > 1 && data[k/2].comparaTo(data[k]) < 0 ) {
			swap(k, k/2);
			k /= 2;
		} 
	}
	
	//shiftDown操作
	private void shiftDown(int k) {
		while( 2*k <= count ) {
			int j = 2*k;
			if ( j+1 <= count && data[j + 1].compareTo(data[j]) > 0)
				j++;
			if ( data[k].compareTo(data[j]) >= 0 ) break;
			swap(k, j);
			k = j;
		}
		System.out.println("shiftDown结束");
	}

	//测试 HeapShiftDown
	public static void main(String[] args) {
		HeapShiftDown<Integer> heapShiftDown = new HeapShiftDown<Integer>(100);
		// 堆中元素个数
		int N = 100;
		// 堆中元素取值范围[0, M)
		int M = 100;
		for ( int i = 0 ; i < N ; i ++ )
			heapShiftDown.insert( new Integer((int)(Math.random() * M)) );
		Integer[] arr = new Integer[N];
		// 将最大堆中的数据逐渐使用extractMax取出来
		// 取出来的顺序应该是按照从大到小的顺序取出来的
		for ( int i = 0 ; i < N ; i ++ ){
			arr[i] = heapShiftDown.extractMax();
			System.out.print(arr[i] + " ");
		}
		// 确保arr数组是从大到小排序的
		for ( int i = 1; i < N ; i ++ )
			assert arr[i - 1] >= arr[i];
	}
}

4.基础的堆排序

package runoob.heap;

import runoob.sort.SortTestHelper;

/**
* 用heapify进行堆排序
*/
public class Heapify<T extends Comparable> {
	protected T[] data;
	protected int count;
	protected int capacity;
	
	//构造函数,通过一个给定数组创建一个最大堆
	//该构造堆的过程中,时间复杂度为O(n)
	public class Heapify<T extends Comparable> {
		int n = arr.length;
		data = (T[])new Comparable[n + 1];
		capacity = n;

		for(  int i = 0; i < n ; i ++ )
			data[ i + 1] = arr[i];
		count = n;
		//从第一个不是叶子节点的元素开始
		for(  int i = count/2 ; i >= 1; i -- )
			shiftDown(i);
	}	
	//返回堆中的元素个数
	public int size() {
		return count;
	}
	//返回一个布尔值,表示堆中是否为空
	public boolean isEmpty(){
		return count == 0;
	}
	// 像最大堆中插入一个新的元素 item
	public void insert(T item) {
		assert count + 1 <= capacity;
		data[count + 1] = item;
		count ++;
		shiftUp(count);
	} 
	// 从最大堆中取出堆顶元素, 即堆中所存取的最大数据
	public T extractMax() {
		assert count > 0;
		T ret = data[1];
		swap( 1 , count );
		count --;
		shiftDown();
		return ret;
	}
	//获取最大堆中的堆顶元素
	public T getMax() {
		assert( count > 0 );
		return data[1];
	}
	//交换堆中索引为 i和j 的两个元素
	private void swap(int i, int j) {
		T t = data[i];
		data[i] = data[j];
		data[j] = t;
	}
	//最大堆核心辅助函数
	private void shiftUp(int k) {
		while( k > 1 && data[k/2].compareTo(data[k]) < 0 ){
			swap(k, k/2);
			k /= 2;
		}
	}
	private void shiftDown(int k){
		while( 2*k <= count ){
			int j = 2*k;
			if ( j+1 <= count && data[j+1].compareTo(data[j]) > 0 )
					j++;
			// data[j] 是data[2*k]和data[2*k+1] 中的最大值

			if( data[k].compareTo(data[j]) >= 0 ) break;
			swap(k,j);
			k = j;
		}
	}
	//测试 heapify
	public static void main(String[] args) {
		int N = 100;
		Integer[] arr = SortTestHelper.generateRandomArray(N, 0, 100000);
		Heapify<Integer> heapify = new Heapify<Integer>(arr);
		// 将heapify中的数据逐渐使用extractMax取出来
		// 取出来的顺序应该是按照从大到小的顺序取出来的
		for ( int i = 0; i < N; i++ ){
			arr[i] = heapify.extractMax();
			System.out.print(arr[i] + " ");
		}

		//确保arr数组是从大到小的排列的
		for( int i = 1 ; i < N; i ++ )
			assert arr[i-1] >= arr[i];
	}
}

5.优化堆排序

package runoob.heap;

import runoob.sort.SortTestHelper;
/**
* 原地堆排序
*/
public class HeapSort<T extends Comparable> {
	
	public static void sort(Comparable[] arr) {
		
		int n = arr.length;

		//注意, 此时我们的堆是从0开始索引的
		//从(最后一个元素的索引 - 1)/2 开始
		// 最后一个元素的索引 = n - 1
		for (int i = (n - 1 - 1) / 2; i >= 0; i-- )
			shiftDown(arr, n, i);
		for (int i = n - 1; i > 0; i--) {
			swap(arr, 0, i);
			shiftDown(arr, i, 0);
		}
	}
	//交换堆中的索引为i和j的两个元素
	private static void swap(Object[] arr, int i, int j) {
		Object t = arr[i];
		arr[i] = arr[j];
		arr[j] = t;
	}
	// 原始的siftDown过程
	private static void shiftDown(Comparable[] arr, int n, int k){
		while (2* k + 1 < n) {
			//左孩子节点
			int j = 2*k +1;
			//右孩子节点比左孩子节点大
			if (j + 1 < n && arr[j + 1].compareTo(arr[j]) > 0)
				j += 1;
			// 比两孩子节点都大
			if (arr[k].compareTo(arr[j]) >= 0) break;
			// 交换源节点和孩子节点的值
			swap(arr, k, j)
			k = j;
		}
	}
	// 测试 HeapSort
	public static void main(String[] args) {
		int N = 100;
		Integer[] arr = SortTestHelper.generateRandomArray(N, 0, 100000);
		sort(arr);
		// 将heapify中的数据逐渐使用extractMax取出来
		// 取出来的顺序应该是按照从大到小的顺序取出来
		for (int i = 0; i < N; i++) {
			System.out.print(arr[i] + " ");
		}
		// 确保arr数组是从大到小排列的
		for (int i = 1; i < N; i++)
			assert arr[i - 1] >= arr[i];
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值