排序算法(四)-- 堆排序

堆排序


思想


将初始待排序关键字序列(R0,R2....Rn-1)构建成大顶堆。


将堆顶元素R[0]与最后一个元素R[n-1]交换,此时得到新的无序区(R0,R1,R2,......Rn-2)和新的有序区(R[n-1]),且满足R[0,2...n-2]<=R[n-1]; 


由于交换后新的堆顶R[0]可能违反堆的性质,因此需要对当前无序区(R0,R1,R2,......Rn-2)调整为新堆,然后再次将R[0]与无序区最后一个元素交换,得到新的无序区(R0,R2....Rn-3)和新的有序区(R[n-1],R[n-2])。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。


示例




n=11,i=n/2-1 to 0 ,调用heapify(array,i,n-1)把堆调整为大顶堆




依次循还……


至此大顶堆就建好了!


然后,array0】与array10】交换


此时100已经在正确的位置上,此时再维护array【0】至array【9】的堆


然后array【0】与array【9】交换,循还下去……


关键代码


	//构建大顶堆
	public static void buildHeap(int[] array,int n){
		//非叶子结点的操作
		for(int i=n/2-1;i>=0;i--){
			heapify(array,i,n-1);
		}
	}
	//调整大顶堆
	public static void heapify(int[] array,int index,int max){
		int left=2*index+1;
		int right=2*index+2;
		int largest = index;
		if(left<=max&&array[largest]<array[left]){
			largest=left;
		}
		if(right<=max&&array[largest]<array[right]){
			largest=right;
		}
		//如果任一子节点比父节点大则交换,之后维护下级节点
		if(largest!=index){
			swap(array,index,largest);
			heapify(array,largest,max);
		}
	}
	//堆排序
	public static void HeapSort(int[] array,int n){
		buildHeap(array,n);
		//建堆之后依次交换并调整维护为新的大顶堆
		for(int i=n-1;i>0;i--){
			swap(array,0,i);
			heapify(array,0,i-1);
		}
	}
	public static void swap(int[] array,int i,int j){
		int temp;
		temp=array[i];
		array[i]=array[j];
		array[j]=temp;
	}


复杂度

“空间复杂度”指占内存大小,堆排序每次只对一个元素操作,是就地排序,所用辅助空间O(1),空间复杂度是O(1)。构建堆的时间复杂度是O(nlogN)。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值