堆排序
堆排序原理:数组表示堆,若根节点存在序号0处,i节点的父节点就为(i-1)/2。i节点的左右节点下标分别是2*i+1和2*i+2.
若是升序排序,则建立大顶堆,反之若是降序排序,则建立小顶堆。
堆排序是首先建堆,输出堆顶元素,将堆顶元素与最后一个元素交换,这样第n个位置作为有序区,前n-1个位置为无序区,对无序区不断进行上述操作,直到有序去增长到n-1,则排序完成。
时间效率:
O(n∗log2n)
空间效率:
O(1)
算法稳定性:不稳定
import java.util.Scanner;
//堆排序(从小到大排序)
public class Sort_h{
public void heapSort(int nums[]){
int len = nums.length;
for(int i = 0;i<len-1;i++){
buildHeap(nums,len-i-1);//建堆
//交换堆顶元素
swap(nums,0,len-i-1);
}
System.out.println(java.util.Arrays.toString(nums));
}
//建立大顶堆
private void buildHeap(int []nums,int length){
int len = length;
for(int i =(len-1)/2;i>=0;i--){
int left = i*2+1;//左节点
//判断右节点是否存在且是否大于左节点
if(left<len){
if(nums[left]<nums[left+1]){
left++;
}
}
//判断父节点是否大于子节点
if(nums[i]<nums[left]){
int temp = nums[i];
nums[i] = nums[left];
nums[left] = temp;
}
}
}
//交换函数
private void swap(int nums[],int i,int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
//测试函数
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int nums[] = new int[10];
for(int i = 0;i<10;i++){
nums[i] = scanner.nextInt();
}
scanner.close();
Sort_h test = new Sort_h();
test.heapSort(nums);
}
}