堆排序

本文介绍了堆排序算法,重点讨论了二叉堆的应用,如最优队列和堆排序。堆排序利用最大堆性质,通过insertNode插入节点,deleteMax删除最大元素,以及build_max_heap构建堆。此外,还提供了heapSort()的实现,用于对无序数组进行排序。


二叉堆:是被完全填满的二叉树,唯一的例外是在最底层。

二叉堆的应用范围:最优队列(最小堆)、堆排序(最大堆)


内部需要用到的数据结构为数组,并且为了方便处理,一般从数组下标index=1开始填充。

需要有以下几个方法:

1. insertNode往最大堆插入一个节点

2.deleteMax删除最大堆中最大的元素并返回

3.build_max_heap根据一个无序数组构造一个最大堆

4.heapSort()


基本类结构如下代码:

public class MaxHeap<AnyType extends Comparable<? super AnyType>>  {
	private int currentSize=0; //当前二叉堆中的元素个数
	private final static int DEFAULT_SIZE=10; //数组默认的大小
	private AnyType[] array;//从数组下标index=1开始保存堆的值
	
	public MaxHeap()
	{
		array = (AnyType[]) new Comparable[DEFAULT_SIZE];
	}
	
	public MaxHeap(int capacity)
	{
		array = (AnyType[]) new Comparable[capacity+1];
	}
	
	public MaxHeap(AnyType[]items)
	{
		if(items==null)
		{
			System.out.println("arrsy items is empty");
			return;
		}
		this.array=(AnyType[]) new Comparable[items.length+1];
		for(int index=0;index<items.length;index++)
		{
			array[index+1] = items[index];
		}
	}
}



insertNode&&build_max_heap:

public void build_max_heap()
	{
		build_max_heap(array);
	}
	
	private void build_max_heap(AnyType []outArray)
	{
		for(int index=1;index<outArray.length;index++)
		{
			insertNode(outArray[index]);
		}
	}
	
	public void insertNode(AnyType node)
	{
		if(++currentSize>=array.length)
		{
			System.out.println("数组array的下标currentSize:"+currentSize+"长度越界");
			return;
		}
		
		array[currentSize] = node;
		
		int indexFlag = currentSize;
		while(indexFlag!=1)
		{
			if(array[indexFlag/2].
					compareTo(array[indexFlag])<0)
			{
				swap(indexFlag, indexFlag/2);
			}
			indexFlag = indexFlag/2;
		}
	}
/**
<span style="white-space:pre">	</span> * 交换数组array两个不同下标的值
<span style="white-space:pre">	</span> * @param index1
<span style="white-space:pre">	</span> * @param index2
<span style="white-space:pre">	</span> */
<span style="white-space:pre">	</span>private void swap(int index1,int index2)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>AnyType tmp = array[index1];
<span style="white-space:pre">		</span>array[index1] = array[index2];
<span style="white-space:pre">		</span>array[index2] = tmp;
<span style="white-space:pre">	</span>}


deleteMax:

/**
	 * 删除最大的节点
	 * @return
	 */
	public AnyType deleteMax()
	{
		if (this.currentSize<1) {
			System.out.println("空二叉堆,无法执行deleteMax操作");
			return null;
		}
		
		/**
		 * 确保删除最大节点后,还满足二叉堆的结构性
		 * */
		swap(1, currentSize);
		currentSize--;
		this.makeSureOrder(1);
		return array[currentSize+1];
	}
	
	/**
	 * 当二叉堆的跟节点失去堆序性时,
	 * 通过此方法保证二叉堆的堆序性
	 */
	public void makeSureOrder(int indexFlag)
	{
		AnyType tmp = array[indexFlag];
		int child;
		
		/**
		 * 只要indexFlag还有子节点,则需要继续遍历
		 */
		while(2*indexFlag<=currentSize)
		{
			/**
			 * 找到indexFlag的第一个子节点
			 */
			child = 2*indexFlag;
			
			/**
			 * 如果存在右子节点,并且右子节点大于左子节点,
			 * 则child右移
			 */
			if(2*indexFlag<currentSize&&array[child+1].compareTo(array[child])>0)
			{
				child++;
			}
			
			if(array[child].compareTo(tmp)>0)
			{
				array[indexFlag] = array[child];
				indexFlag = child;
			}
			else {
				break;
			}
		}
		
		array[indexFlag] = tmp;
	}

heapSort:

/**
	 * 对数组堆排序
	 */
	public void heapSort(AnyType[] outArray)
	{
		this.build_max_heap();
		if(this.currentSize<1)
		{
			System.out.println("空二叉堆");
			return;
		}
		
		int length = currentSize;
		for(int index=1;index<=length;index++)
		{
			deleteMax();
		}
		
		/**
		 * 对数组从小到大排序后的结果:
		 */
		System.out.println("对数组从小到大排序后的结果:");
		
		for(int index=1;index<=length;index++)
		{
			System.out.println(array[index]);
		}
	}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值