选择排序——堆排序

堆排序

一个堆需要满足两个条件:
  1. 是一颗完全二叉树(节点从上到下,从左到右)
  2. 每个节点大于它自生的两个子节点,成为大根堆(或者每个节点小于它两个子节点,称为小根堆)
    在这里插入图片描述
堆排序的核心思想:
1. 创建堆:
  • 从最后一个父节点 i 开始直到起始节点依次做heapify

  • 创建堆的重要方法——heapify(下面有图片样例): 若对节点 i 进行heapify操作,就是从节点 i 和其两个子节点中选择一个最大的与节点i交换,这里有两种情况:
          1.若最大的在子节点中,交换后再对交换位子的子节点做heapify,直到最后一个节点为止。
          2.若最大节点为本身,则结束

  • 堆中的父节点和子节点求法:
          parent =(i - 1)/ 2;
          c1=2i + 1;
          c2=2i + 2;

2. 对堆进行排序:
  • 从最后一个元素i开始,依次向前递减(i- -),对于每次的i都与当前的首节点交换位置,交换位置后立刻对首节点进行n-i的heapify操作,(因为此时堆被破坏),又因为只有首元素被破坏,所以只需要heapify(tree,n-i,0)即可重建堆.当i为0时,即排序完成。
  • 在这里插入图片描述
时间复杂度:
  • O(nlog2^n)
稳定性
  • 不稳定(在建堆的时候或者进行heapify时都可能交换原本相同的两个元素)
    在这里插入图片描述
java源码
public class HeapSort {
	//heapify函数
	public static void heapify(int []tree,int n,int i){
		if(i==n){//到最后节点跳出
			return;
		}
		int c1=2*i+1;
		int c2=2*i+2;
		int maxIndex=i;
		if(c1<n&&tree[c1]>tree[maxIndex]){//获得最小节点位置
			maxIndex=c1;
		}
		if(c2<n&&tree[c2]>tree[maxIndex]){//获得最小节点位置
			maxIndex=c2;
		}
		if(maxIndex!=i){
			int temp=tree[maxIndex];tree[maxIndex]=tree[i];tree[i]=temp;
			heapify(tree,n,maxIndex);//再将交换节点位置处的元素进行heapify操作
		}
	}
	//创建堆
	public static void build_heap(int []tree){
		int last_node=tree.length-1;
		int last_parent=(last_node-1)/2;//从最后一个父节点开始,向前依次做heapify操作
		for(int i=last_parent;i>=0;i--){
			heapify(tree,tree.length,i);
		}
	}
	//堆排序
	public static void heap_sort(int[]tree){
		build_heap(tree);//先建堆
		for(int i=tree.length-1;i>=0;i--){//i从最后一个元素开始,依次向前(i--),分别与首节点交换位置,交换位置后立刻对首节点进行n-i的heapify操作,这样能保证每次交换的首元素都是最大的
			int temp=tree[i];
			tree[i]=tree[0];
			tree[0]=temp;
			heapify(tree,i,0);
		}
	}
	public static void main(String[] args) {
		//测试
		int []a={2,5,3,1,11,5,5,595,9,5,4,4,8,4,54,1,1,12,1,10,4};
		heap_sort(a);
		for(int t:a)System.out.println(t);
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值