堆排序

堆排序(Heap Sort)
  • 堆排序是一种树形选择排序,在排序过程中将待排记录r[1…n]看成是一颗完全二叉树的顺序结构存储,利用完全二叉树中双亲结点和孩子结点之间的关系,在当前无序的序列中选择关键字最大或者最小的记录。是不稳定排序。
  • 堆排序是使用的完全二叉树中大根堆(小根堆)的堆顶记录最大(最小)的性质进行排序的。
  • 算法步骤:
    • 1.按定义将待排记录r[0…n]调整为大根堆,交换r[0]与r[n],则r[n]为关键字最大的记录。
    • 2.将r[0…n-1]从新调整为大根堆,交换记录r[0]与r[n-1],则r[n-1]为关键字次大的记录。
    • 3.循环n-1次,直到交换了r[0]和r[1]为止。
  • 示例过程:

初始序列[49,38,65,97,76,13,27,49]
image

第一次调整序列[49,97,65,49,76,13,27,38]
image

第二次调整序列[97,76,65,49,49,13,27,38],成功找出最大值97
image

首尾交换,将最大值交换到末尾
image

一趟排序结果[38,76,65,49,49,13,27,97]
image

开始第二趟筛选[38,76,65,49,49,13,27,97]
image

成功找出最大值76:[76,49,65,38,49,13,27,97]
image

进行首尾交换[27,49,65,38,49,13,76,97],第二趟排序完成
image

继续进行建堆交换操作……

  • 代码实现:
    #include<iostream>
    using namespace std;
    
    void adjust_heap(int *array, int s, int m){
    	int j, key=array[s];    //取处结点s处的值
    	for(j=2*s+1; j<=m; j*=2){
    		if(j<m&&array[j]<array[j+1])   //找出值大的孩子结点
    			j++;
    		if(key>array[j])  //s为值较大的结点,退出循环
    			break;
    		array[s]=array[j];   //否则将值较大的结点调整到s
    		s=j;   //继续对子节点j进行调整
    	}
    	array[s]=key;  //将原来结点值插入
    }
    
    void creat_heap(int *array, int n){
    	int i;
    	for(i=n/2; i>=0; i--)  //i=n/2是从末尾结点的双亲结点开始调整
    		adjust_heap(array, i, n);
    }
    
    int main(){
    	int data[]={49,38,65,97,76,13,27,49};
    	int i=0;
    
    	creat_heap(data, 7);
    
    	for(i=7; i>0; i--){
    		int temp;
    		temp=data[0];
    		data[0]=data[i];
    		data[i]=temp;
    		adjust_heap(data, 0, i-1);
    	}
    
    	for(i=0; i<8; i++){
    		cout<<data[i]<<" ";
    	}
    	return 0;
    }
    
    
    Output:13 27 38 49 49 65 76 97

仅需要一个供交换的辅助存储空间,故空间复杂度为O(1)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值