合併排序

思想:二分法,類似於二叉樹的形式,不斷的拆分,知道每個部分的個數爲1,然後返回到根元素,進行排序。

#include <stdio.h>


//合併子序列
void merge(int array[], int start, int mid, int end)
{
	int len_l = mid - start + 1; 		// 左子串長度
	int len_r = end - mid;			//右子串長度
	int len = 0, len_max = 0;		//len:兩個字串小值,len_max:兩子串長度之和
	int l = start, r = mid + 1;		//l:左子串遍歷,r:右子串遍歷
	int m = 0;				//局部變量數組索引

	//獲取兩個子串較小值
	if(len_l > len_r)
	{
		len = len_r;
	}
	else
	{
		len = len_l;
	}
	len_max = end - start + 1;
	int array_t[len_max];
	for(m = 0; len_r != 0 && len_l != 0; m++)
	{
		//取兩子串的小值保存
		if(array[l] < array[r])
		{
			array_t[m] = array[l];
			l++;
			len_l--;
		}
		else
		{
			array_t[m] = array[r];
			r++;
			len_r--;
		}
	}
	//其中一條子串爲0,則需要將另一條子串的剩餘部分連接到局部數組中
	if(len_l == 0)
	{
		while(len_r)
		{
			array_t[m++] = array[r++];
			len_r--;
		}
	}
	else if(len_r == 0)
	{
		while(len_l)
		{
			array_t[m++] = array[l++];
			len_l--;
		}
	}
	//將局部數組的值拷貝到原數組
	for(m = 0; m < len_max; m++)
	{
		array[start + m] = array_t[m];
	}
}

//拆分子序列
void split(int array[], int start, int end)
{
	int i = 0, j = 0;
	int mid;
	if(start == end)
	{
		return;
	}
	else
	{
		mid = start + (end - start) / 2;
		//拆分成兩條子串
		split(array, start, mid);  
		split(array, mid + 1, end);
		//按順序合併
		merge(array, start, mid, end);
	}
	return;
}

int main()
{
	int array[8] = {3, 41, 52, 26, 38, 57, 9, 49};	
	split(array, 0, 7);
	int i = 0;
	for(i = 0; i < 8; i++)
	{
		printf("%d ", array[i]);

	}
	printf("\n");
}

点赞