您的位置:首页 > 其它

算法导论第六章6.5有限队列中的6.5-9课后练习

2014-01-05 14:20 417 查看
由题目提示知,需要用到归并排序,又要用到最小堆,那么我想到用含有最小堆排序的归并排序对k个有序数组进行合并因为链表可以看成特殊的动态数组,那么我把链表替换成数组求解。先把k个数组放入到一个新数组A中,那么一共就有k=n/a个数组(a为k个元素数组中所含最多元素的数量)

#include <iostream>
using namespace std;
const length=100;
int LEFT(int i);
int RIGHT(int i);
void MIN_HEAPIFY(int A[],int i);
void BUILD_MIN_HEAP(int A[],int p,int q);
int*  HEAPSORT(int A[],int B[],int p,int q,int r);
void MERGE(int A[],int p,int q,int r);
void MERGE_SORT(int A[],int p,int r,int k);
int heap_size=length,a=4;
void main()
{
int B[8][4]={{8,16,19},{1,9},{2,10,17,20},{3,11},{4,12},{5,13},{6,14,18},{7,15}};//这是k=8个数组在一个2维数组中
int A[length]={0};
for(int i=0,h=0;i<8;i++)//将k=8个数组合并到一个新数组中。
{
for (int j=0;j<4;j++,h++)
{
if(B[i][j]!=0) A[h]=B[i][j];
}
}//这个双重循环含k*a=n个元素 运行时间为O(n)
MERGE_SORT(A,0,length-1,a);//然后将新数组每a=4个有序数进行归并,注意a值的选择 2<=a<=√总元素n (注释1)
cout<<"排序后:"<<endl;
for (  i=0;i<length;i++)
{
if(A[i]>0)
cout<<A[i]<<" ";
}
cout<<endl;
}
int LEFT(int i)
{
return 2*i+1;
}
int RIGHT(int i)
{
return 2*i+2;
}
void MIN_HEAPIFY(int A[],int i)
{
int largest=0;
int L=LEFT(i);
int R=RIGHT(i);
if (L<heap_size&&A[L]<A[i])
{
largest=L;
}
else largest=i;
if (R<heap_size&&A[R]<A[largest])
{
largest=R;
}
if (largest!=i)
{
swap(A[i],A[largest]);
MIN_HEAPIFY(A,largest);
}
}
void BUILD_MIN_HEAP(int A[],int p,int q)
{
heap_size=q;
for (int i=q/2;i>=p;i--)
{
MIN_HEAPIFY(A,i);
}
}
int* HEAPSORT(int A[],int B[],int p,int q,int r)
{
for (int i=p,j=0;i<=q,j<r;i++,j++)
{
B[j]=A[i];
}
BUILD_MIN_HEAP(B,0,r);
for ( i=r-1;i>=1;i--)
{
swap(B[0],B[i]);
heap_size--;
MIN_HEAPIFY(B,0);
}
return B;
}
void MERGE(int A[],int p,int q,int r)
{
int n1=q-p+1,n2=r-q,i,j,flag=-1;
int *L=new int[n1];
int *R=new int[n2];
L=HEAPSORT(A,L,p,q,n1);//归并时,用最小堆排序
R=HEAPSORT(A,R,q+1,r,n2);
i=0;j=0;
L[n1]=flag;
R[n2]=flag;
for (int k=p;k<=r;k++)
{
if (L[i]==flag)
{
A[k]=R[j];
j++;
}
else if (R[j]==flag)
{
A[k]=L[i];
i++;
}
else if (L[i]>=R[j])
{
A[k]=L[i];
i++;
}
else
{
A[k]=R[j];
j++;
}
}
}
void MERGE_SORT(int A[],int p,int r,int k)
{
int q=(r+p)/k;
if((q-p+1)<k)
{
return;
}
else
{
MERGE_SORT(A,p,q,k);
MERGE_SORT(A,q+1,r,k);
MERGE(A,p,q,r);
}
}


注释1:详情见这个是带有插入排序的归并算法(此链接里面的k元素长度值相当于这里的a元素长度值)也就是每个有序数组(共k个)含有有效元素的长度不能大于总元素的开方,这是能够正确进行归并排序的先决条件。这个归并排序,运行时间为O(nlgn),没有到达O(nlgk),实在想不出如何缩短运行时间的方法了。


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: