1. 程式人生 > >經典排序之多路歸併

經典排序之多路歸併

#include <iostream>
using namespace std;

#define LEN 10			//最大歸併段長
#define MINKEY -1     //預設全為正數
#define MAXKEY 100    //最大值,當一個段全部輸出後的賦值

struct Array
{
	int arr[LEN];
	int num;
	int pos;
}*A;

int k,count;
int *LoserTree,*External;

void Adjust(int s)
{
	int t=(s+k)/2;//ls[t]是b[s]的雙親結點的下標
	int temp;
	while(t>0)
	{
		if(External[s] > External[LoserTree[t]])
		{
			temp = s;
			s = LoserTree[t];
			LoserTree[t]=temp;
		}
		t=t/2;
	}
	LoserTree[0]=s;
}

void CreateLoserTree()
{
	External[k]=MINKEY;
	int i;
	for(i=0;i<k;i++)LoserTree[i]=k;//設定ls中敗者的初值,簡化了敗者樹的建立過程,這樣就可以直接通過(調整過程)來建立敗者樹。
	for(i=k-1;i>=0;i--)Adjust(i);
}

void K_Merge()
{
	int i,p;
	//初始化External陣列,用以接下來建立LoserTree
	for(i=0;i<k;i++)
	{
		p = A[i].pos;
		External[i]=A[i].arr[p];
		//cout<<External[i]<<",";
		A[i].pos++;
	}
	//建立LoserTree
	CreateLoserTree();
	int NO = 0;
	//輸出最小值,並替代調整
	while(NO<count)
	{
		p=LoserTree[0];
		cout<<External[p]<<",";
		NO++;
		if(A[p].pos>=A[p].num)External[p]=MAXKEY;
		else 
		{
			External[p]=A[p].arr[A[p].pos];
			A[p].pos++;
		}
		Adjust(p);
	}
	cout<<endl;
}

int main()
{
	//freopen("in.txt","r",stdin);

	int i,j;
	count=0;
	cin>>k;
	A=(Array *)malloc(sizeof(Array)*k);
	for(i=0;i<k;i++)
	{
		cin>>A[i].num;
		count=count+A[i].num;
		for(j=0;j<A[i].num;j++)
		{
			cin>>A[i].arr[j];
		}
		A[i].pos=0;
	}
	LoserTree=(int *)malloc(sizeof(int)*k);
	External=(int *)malloc(sizeof(int)*(k+1));

	K_Merge();
	system("pause");
	return 0;
}