歸併排序C++實現

//merge sort

//歸併排序是通過將兩個有序的數列合併成一個有序的數列的排序過程;
//具體流程可以看成一個樹形結構,最底層是兩個結點合併,往上合併的結點個數越多,所以時間複雜度爲O(nlgn);


#include<iostream>
#include<vector>

using namespace std;

//二路歸併,當然也可以多路歸併,核心
template<class type>
void merge(vector<type>& vec,int start,int mid,int end)
{//合併過程,將[start,mid],[mid+1,end]兩個有序的數列合併成一個有序數列,並放到[start,end]中
	vector<type> tmpVec(end-start+1,0);//臨時數組,歸併排序的時間複雜度爲O(n);
	int index=0;
	int i=start;
	int j=mid+1;
	
	while(i<=mid && j<=end)
	{
		if(vec[i]<vec[j])
			tmpVec[index++]=vec[i++];
		else
			tmpVec[index++]=vec[j++];
	}

	while(i<=mid)
		tmpVec[index++]=vec[i++];

	while(j<=end)
		tmpVec[index++]=vec[j++];

	for(int k=start;k<=end;++k)//將歸併後的數列複雜回原數組
	{
		vec[k]=tmpVec[k-start];
	}
}

//循環方法
template<class type>
void mergeSort_l(vector<type>& vec)
{
	int gap=1;//初始gap
	int length=vec.size();

	while(gap<length)
	{
		int i;
		for(i=0;i+2*gap-1<length;i+=2*gap)
		{
			merge(vec,i,i+gap-1,i+2*gap-1);
		}

		if(i+gap-1<length)//最後還剩下兩個未合併數列
		{
			merge(vec,i,i+gap-1,length-1);
		}
		gap*=2;//gap增加
	}	
}


//遞歸方法
template<class type>
void mSort(vector<type>& vec,int start,int mid,int end)
{
	if(start==end)
		return;
	else
	{
		mSort(vec,start,(start+mid)/2,mid);//先歸併左半子區間
		mSort(vec,mid+1,(mid+end+1)/2,end);//再歸併右半子區間
		merge(vec,start,mid,end);//最後將兩個子區間合併爲一個
	}
}

template<class type>
void mergeSort_r(vector<type>& vec)
{
	int length=vec.size();
	mSort(vec,0,length/2,length-1);
}

int main()
{
	int a[10]={5,8,9,6,7,2,1,3,0,4};
	vector<int> vec(a,a+10);

	mergeSort_r(vec);

	for(int i=0;i<vec.size();++i)
	{
		cout<<vec[i]<<"   ";
	}
	return 0;
}

發佈了143 篇原創文章 · 獲贊 14 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章