置换选择排序

置换选择排序

描述


给定初始整数顺串,以及大小固定并且初始元素已知的二叉最小堆(为完全二叉树或类似完全二叉树,且父元素键值总小于等于任何一个子结点的键值),要求利用堆实现置换选择排序,并输出第一个顺串。例如给定初始顺串29,14,35,13,以及堆(记为16 19 31 25 21 56 40), 置换选择排序得到的第一个顺串为16 19 21 25。

输入
第一行包含两个整数,m为初始顺串的数的个数,n为二叉最小堆的大小
第二行包含m个整数,即初始顺串
第三行包含n个整数,即已经建好的堆的元素(有序,按照从堆顶到堆底,从左到右的顺序)
输出
输出包含一行,即第一个顺串。
样例输入
4 7
29 14 35 13
16 19 31 25 21 56 40
样例输出

16 19 21 25
参考代码:

#include <stdio.h>
#include<iostream> 
using namespace std;
int m,size;
int str[1001];
int A[1001];
class MinHeap { // 最小堆ADT定义
public:
	int * heapArray; // 存放堆数据的数组
 	int CurrentSize; // 当前堆中元素数目
 	int MaxSize; // 堆所能容纳的最大元素数目
 	void BuildHeap(); // 建堆
 	MinHeap(int* array,const int n); // 构造函数,n为最大元素数目
 	void SiftDown(int left); // 筛选法
};
void MinHeap::SiftDown(int position) {
	int i=position; //标识父结点
	int j=2*i+1; //标识关键值较小的子结点
	int  temp=heapArray[i]; //保存父结点
	while (j<CurrentSize){ //过筛
 		if ((j<CurrentSize-1)&&(heapArray[j]>heapArray[j+1]))
 			j++; //j指向数值较小的子结点
 		if (temp>heapArray[j]){
 			heapArray[i]=heapArray[j];
 			i=j; j=2*j+1; //向下继续
 		} else break;
	}
	heapArray[i]=temp;
}
void MinHeap::BuildHeap() {
	for (int i=CurrentSize/2-1; i>=0; i--) //反复调用筛选函数
		SiftDown(i);
} 
MinHeap::MinHeap(int *array,const int n) {
	CurrentSize=n;
	MaxSize=n; //初始化堆容量为n
	heapArray=new int [MaxSize]; //创建堆空间
	for(int i=0;i<n;i++){
		heapArray[i] = array[i];
	}
	BuildHeap(); //此处进行堆元素的赋值工作
}
void replacementSelection(int *A){
	//建立最小值堆
	MinHeap H(A,size);
	int last = size-1;
	int len = m<last? m:size;
	for(int i=0; i<len; i++){
		cout<<H.heapArray[0]<<" ";  	//堆的最小值
		if(str[i]>=H.heapArray[0]) 	H.heapArray[0] = str[i];
		else  {//否则用last位置记录代替根结点,把r放到last
			H.heapArray[0] = H.heapArray[last];
			H.heapArray[last] = str[i];
			H.CurrentSize--;
			last--;
		} 
	    if (last!=0) 
			H.SiftDown(0);  //堆调整 
  	}
}
int main(){
	cin>>m>>size;
	int i;
	for(i=0;i<m;i++){
		cin>>str[i];
	}
	for(i=0;i<size;i++)
		cin>>A[i];
	replacementSelection(A);
	return 0;
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值