合并堆算法
YOYO
posted @ 2009年3月10日 21:31
in 【算法】与【数据结构】
with tags
堆
, 4975 阅读
编写一个算法,把两个相同大小的堆合并成一个堆。
-
/*
-
* Title: 编写一个算法,把两个相同大小的堆,合并成一个堆。
-
* Author: YOYO
-
* Time: 2009-3-8
-
*
-
* 合并算法即其中的merge_heaps(Type A[], Type B[], Type C[], int n)
-
* 该算法将两个相同大小的堆A和B合并为一个大顶堆,并存储到C中。时间复杂度为O(n*log(n))
-
*
-
*/
-
#include<iostream>
-
using namespace std;
-
-
#define Type int
-
#define N 100
-
-
void shift_up(Type H[], int i);
-
void shift_down(Type H[], int n, int i);
-
void insert(Type H[], int &n, Type x);
-
void del(Type H[], int &n, int i);
-
Type delete_max(Type H[], int &n);
-
void print_heap(Type H[], int n);
-
void make_heap(Type H[], int n);
-
void heap_sort(Type H[], int n);
-
void merge_heaps(Type A[], Type B[], int n);
-
-
void shift_up(Type H[], int i){
-
bool done = false;
-
while(i!=1){
-
if(H[i]<=H[i/2]){
-
break;
-
}
-
swap(H[i], H[i/2]);
-
i /= 2;
-
}
-
}
-
-
void shift_down(Type H[], int n, int i){
-
bool done = false;
-
while( (i=2*i)<=n ){
-
if(i+1<=n&&H[i+1]>H[i]){
-
i ++;
-
}
-
if(H[i/2]>=H[i]){
-
break;
-
}
-
swap(H[i/2], H[i]);
-
}
-
}
-
-
void insert(Type H[], int &n, Type x){
-
n++;
-
H[n] = x;
-
shift_up(H,n);
-
}
-
-
void del(Type H[], int &n, int i){
-
Type x, y;
-
x = H[i], y = H[n];
-
n--;
-
if(i<=n){
-
H[i] = y;
-
if(y>=x){
-
shift_up(H,i);
-
}else{
-
shift_down(H,n,i);
-
}
-
}
-
}
-
-
Type delete_max(Type H[], int &n){
-
Type x = H[1];
-
del(H, n, 1);
-
return x;
-
}
-
-
void heap_sort(Type H[], int n){
-
make_heap(H,n);
-
for( int i = n; i>1; i--){
-
swap(H[1],H[i]);
-
shift_down(H,i-1,1);
-
}
-
}
-
-
void print_heap(Type H[], int n){
-
for( int i = 1, j = 1; i<=n; i++){
-
printf("%-4d",H[i]);
-
if((i+1)%j==0){
-
cout<<endl;
-
j*=2;
-
}
-
}
-
cout<<endl;
-
if(i%j)cout<<endl;
-
}
-
-
void make_heap(Type H[], int n){
-
H[n] = H[0];
-
for( int i= n/2; i>=1; i--){
-
shift_down(H,n,i);
-
}
-
}
-
-
/*
-
* 合并堆算法
-
*
-
* 输入:堆A,堆B,堆的长度n
-
* 输出:由堆A和堆B合并成的新大顶堆C
-
*
-
* 该算法执行了2n次时间复杂度为O(log(n))的insert操作,故
-
* 它的执行时间为O(n*log(n))
-
*
-
*/
-
void merge_heaps(Type A[], Type B[], Type C[], int n){
-
int i,k;
-
for(i=1, k = 0; i<=n; i++){
-
insert(C, k, A[i]);
-
}
-
for(i=1, k = n; i<=n; i++){
-
insert(C, k, B[i]);
-
}
-
}
-
-
int main(){
-
int i,n;
-
Type A[N],B[N],C[2*N];
-
-
/* 输入堆的元素 */
-
cout<<"请输入堆的元素个数:";
-
cin>>n;
-
-
cout<<"请输入堆A的元素:";
-
for(i = 0; i<n; i++){
-
cin>>A[i];
-
}
-
-
cout<<"请输入堆B的元素:";
-
for(i = 0; i<n; i++){
-
cin>>B[i];
-
}
-
-
/* 建堆 */
-
make_heap(A,n);
-
make_heap(B,n);
-
-
/* 打印堆*/
-
cout<<"大顶堆A:"<<endl;
-
print_heap(A,n);
-
-
cout<<"大顶堆B:"<<endl;
-
print_heap(B,n);
-
-
/* 合并堆 */
-
merge_heaps(A,B,C,n);
-
-
/* 打印堆*/
-
cout<<"合并后的大顶堆C:"<<endl;
-
print_heap(C,2*n);
-
-
return 0;
-
}
- 无匹配
2010年12月28日 03:07
博主,n个元素重新建堆也不过是O(N)的,哪能用O(nlogn)的算法合并堆呢?
2010年12月29日 23:42
这个算法本身是nlogn的
但是重建堆的方法比这样合并更优 嗯 表示很惭愧