1.codeup-堆-问题 B: 序列合并

97 阅读1分钟

思路

  • 先把temp1[1]与temp2数组中的各个元素和组成一个大小为n的大根堆。
  • 继续插入temp1和temp2数组的其他元素和的组合,如果和小于堆顶(最大值),替换堆顶并调整,最终就保证了n个最小的元素。
  • 对这个堆进行堆排序,输出。

反思

  • 错误思路:把整个数的和放入堆,会数组越界。
  • 学会这种对堆的维护,挑选所选的数据。不一定要全部数据都并入堆
  • 必须选择大根堆,不然无法挑选小值,提示有点问题。
  • 为了节省时间,因为数组是递增的,所有可以进行判断temp1[i]+temp2[j]<=heap[1],不满足就要break掉。

代码

#include<algorithm>
using namespace std;
const int maxn1=100001;
int heap[100001];
int n;
int count1=0;

int temp1[maxn1],temp2[maxn1];

void downAdujust(int low,int high){     //向下调整 
	int i=low,j=2*low;
	while(j<=high){
		if(j+1<=high&&heap[j+1]>heap[j]) j++;
		if(heap[i]>=heap[j]) break;
		swap(heap[i],heap[j]);
		i=j;
		j=2*i;
	}
}

void createHeap(){                      //建堆 
	for(int i=n/2;i>0;i--){
		downAdujust(i,n);
	}
}

void heapSort(){                       //堆排序 
	for(int i=n;i>0;i--){
		swap(heap[1],heap[i]);
		downAdujust(1,i-1);
	}
}

int main(){
	while(scanf("%d",&n)!=EOF){
		count1=0; 
		for(int i=1;i<=n;i++){
			scanf("%d",&temp1[i]);
		}
		for(int i=1;i<=n;i++){
			scanf("%d",&temp2[i]);
			heap[i]=temp1[1]+temp2[i];
		}
		createHeap();
		for(int i=2;i<=n;i++){
			for(int j=1;j<=n;j++){
				if(temp1[i]+temp2[j]<=heap[1]){         //进行新数和堆顶的比较 
					heap[1]=temp1[i]+temp2[j];
					downAdujust(1,n);
				}
				else break;
			}
		}
		heapSort();
		for(int i=1;i<=n;i++) printf("%d ",heap[i]);
		printf("\n");
	}
	return 0;
}