堆排序算法

堆排序  平均时间复杂度为  O(nlogn)   最坏情况下O(nlogn)

原理   (以从小到大为例)

首先将数组中的数据构建大根堆       具体代码如下

        for(i=n/2-1;i>=0;i--){//建成大根堆
            while(2*i+1<n){       //存在左右子树
                j=2*i+1;//左子树
                if((j+1)<n){//右子树存在的情况
                    if(a[j]<a[j+1]) j++;//如果右子树比做左子树大      j指向  右子树
                }
                if(a[i]<a[j]){//如果    子节点大于根节点进行交换
                    t=a[j];
                    a[j]=a[i];
                    a[i]=t;
                    i=j;//调整子树
                }else{
                    break;//不需要调整
                }
            }
        }

构建大根堆结束后下来进行排序     由于是大根对    则根节点就是当前最大值    交换该值重新构造大根堆

重复上述具体代码如下

        for(i=n-1;i>0;i--){//依次遍历
            t=a[0];                //与第i个数据进行交换     将最大值    插入到该在的地方
            a[0]=a[i];
            a[i]=t;
            k=0;
            while(2*k+1<i){//更换根节点后   堆中元素数量减少     重新构造大根堆
                j=2*k+1;//左子树
                if((j+1)<i){//右子树存在的情况
                    if(a[j]<a[j+1]) j++;//如果右子树比做左子树大      j指向  右子树
                }
                if(a[k]<a[j]){
                    t=a[j];
                    a[j]=a[k];
                    a[k]=t;
                    k=j;//调整子树
                }else{
                
                    break;//不需要调整
                }
            
            }
        }


完整代码如下

/*先建成  大根堆    然后每次取a0   的数据此时的数据为最大值     调整堆结构  使最大值依旧在a0 上      
 * flag为true   从小到大      false   从大到小
 */
public class Pile_Sort {
    
    public void pile_sort(int a[],boolean flag){
        int i=0,j=0,h=0,k=0,t;
        int n=a.length;
        for(i=n/2-1;i>=0;i--){//建成大根堆
            while(2*i+1<n){
                j=2*i+1;//左子树
                if((j+1)<n){//右子树存在的情况
                    if(a[j]<a[j+1]) j++;///如果右子树比做左子树大      j指向  右子树
                }
                if(a[i]<a[j]){
                    t=a[j];
                    a[j]=a[i];
                    a[i]=t;
                    i=j;//调整子树
                }else{
                    break;//不需要调整
                }
            }
        }
        for(i=n-1;i>0;i--){//依次遍历
            t=a[0];                //与第i个数据进行交换
            a[0]=a[i];
            a[i]=t;
            k=0;
            while(2*k+1<i){//更换根节点后   堆中元素数量减少
                j=2*k+1;//左子树
                if((j+1)<i){//右子树存在的情况
                    if(a[j]<a[j+1]) j++;///如果右子树比做左子树大      j指向  右子树
                }
                if(a[k]<a[j]){
                    t=a[j];
                    a[j]=a[k];
                    a[k]=t;
                    k=j;//调整子树
                }else{
                
                    break;//不需要调整
                }
            
            }
        }
        if(!flag){//如果flag  为false    则从大到小排序  此时我们交换前后顺序
             n=a.length-1;
            for(i=0;i<a.length/2;i++){
                t=a[i];
                a[i]=a[n-i];
                a[n-i]=t;
            }
        }
    }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值