排序算法之堆排序--Java语言

堆排序算法首先将所有元素(从未排序的数组)插入堆中,然后从堆的根节点依次删除,直到堆空为止。本文主要利用现有数组进行就地排序,具体做法是,当删除一个元素时,只是将数组中的第一个元素与最后一个元素交换位置而不是移除,同时减小堆的大小,即数组大小,然后再对第一个元素进行堆化。持续这个过程直到剩余元素为1.

在数组中直接进行堆排序,需要知道几个参数,即最后一个元素的位置是i=count-1,count为数组大小,则最后一个元素的双亲位置为(count-1)/2。任意一个节点j的左子节点位置l=2*j+1,右子节点位置r=2*j+2.

代码:

public class HeapSort {
	public static void swap(int[] data,int i,int j)
	{
		if(i==j)
			return;
		data[i]=data[i]+data[j];
		data[j]=data[i]-data[j];
		data[i]=data[i]-data[j];
	}
	
	public static int[] heapSort(int[] data)
	{
		for(int i=0;i<data.length;i++)//控制堆大小。
		{
			//每次遍历创建最大堆,并且将堆顶元素放至最后一个,并将遍历的最后一位位置逐个左移。
			createMaxHeap(data,data.length-1-i);//堆化
			swap(data,0,data.length-1-i);//交换第一个元素与最后一个元素,即获取当前最大值
			print(data);
		}
		return data;
	}
	
	public static void createMaxHeap(int[] data,int lastIndex)
	{
		for(int i=(lastIndex-1)/2;i>=0;i--)
		{
			//保存当前正在判断的节点
			int k=i;
			//若当前节点存在
			while(2*k+1<=lastIndex)
			{
				//biggerIndex总是记录较大节点的值,先赋值为当前判断节点的左子节点
				int biggerIndex=2*k+1;
				if(biggerIndex<lastIndex)
				{
					//若右子节点存在,否则此时biggerIndex应该等于lastIndex
					if(data[biggerIndex]<data[biggerIndex+1])
					{
						//若右子节点值比左子节点值大,则biggerIndex记录的是右子节点的值
						biggerIndex++;
					}
				
				}
				if(data[k]<data[biggerIndex])
				{
					//若当前节点值比子节点最大值小,则交换两者的值,交换后将biggerIndex值赋给k
					swap(data,k,biggerIndex);
					k=biggerIndex;
				}
				else
					break;
			}
		}
	}
	
	public static void print(int[] data)
	{
		for(int i=0;i<data.length;i++)
			System.out.print(data[i]+" ");
		System.out.println();
	}
	
	public static void main(String[] args)
	{
		int[] data= {89, 66, 39, 78, 40, 56, 3, 13, 20, 95};
		System.out.println("堆排序的序列变化:");
		int[] ans=heapSort(data);
		System.out.println("堆排序后的序列:");
		for(int i=0;i<data.length;i++)
			System.out.print(data[i]+" ");
	}

}
测试结果:

堆排序的序列变化:
40 89 56 78 66 39 3 13 20 95 
20 78 56 40 66 39 3 13 89 95 
13 66 56 40 20 39 3 78 89 95 
3 40 56 13 20 39 66 78 89 95 
3 40 39 13 20 56 66 78 89 95 
3 20 39 13 40 56 66 78 89 95 
13 20 3 39 40 56 66 78 89 95 
3 13 20 39 40 56 66 78 89 95 
3 13 20 39 40 56 66 78 89 95 
3 13 20 39 40 56 66 78 89 95 
堆排序后的序列:
3 13 20 39 40 56 66 78 89 95 

堆排序主要是堆化的过程,堆化过程中的时间复杂度为O(nlogn),所以堆排序的时间复杂度为O(nlogn)。堆排序是一种就地排序,不需要额外的辅助空间,同时由于在堆化的过程中,元素比较交换次数较多,排序算法不稳定。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值