常見排序算法:歸併排序算法

基本思想:先通過迭代將數組不斷進行二分,最後分成每組只有一個元素,在進行合併,合併是兩兩元素依次比較,放入臨時數組中。

1.首先應對數組進行分開,通過迭代的方法每次二分數組,直到每組只剩一個元素。mid=(start+end) /2。

2.對於上面左邊部分,進行歸併排序, 首先定義i,j兩個指針,分別進行比較,當a[i]<=a[j]時,將a[i]元素放入temp中,同時自增temp中的k和i指針。當a[i]>a[j]時,將a[j]元素放入temp中,同時自增temp中的k和j指針。

3.當j指針指向end時,a[j]<a[i],將a[j]元素放入temp中,同時自增temp中的k和j指針。此時j>end,跳出循環。

4.通過while循環將i中多餘的數據依次存放入temp中。最後將temp中輸入拷貝回數組a中

5.同理對於右半部分也是如此。

6.合併後仍然剩餘兩部分,再利用兩個指針重複上面過程進行i和j中的元素比較,將較小值拷貝至temp中,同時自增i或j指針,k指針。

代碼:

/*歸併排序:
			將兩個已經排好序的數組進行合併即爲歸併
			將待排序的數列分爲若干個長度爲1的子數列,然後將這些數列兩兩合併,得到
			若干個長度爲2的有序數列,再將這些數列兩兩合併以此類推直到合併爲一個數列爲止*/
			//將兩個有序數組合併爲一個有序數組,start:第一個的開始索引,mid:第一個結束索引,end:第二個結束索引
void  Merge(int list[], int start, int mid, int end)
{
	int *tmp = new int[end - start + 1];
	int i = start, j = mid + 1, k = 0;

	while (i <= mid && j <= end)
	{
		if (list[i] <= list[j])//移動兩個指針將比較後的元素放入輔助空間中
		{
			tmp[k++] = list[i++];
		}
		else
		{
			tmp[k++] = list[j++];
		}
	}
	while (i <= mid)//j中已經沒有數據
	{
		tmp[k++] = list[i++];
	}

	while (j <= end)//i中沒有數據
	{
		tmp[k++] = list[j++];
	}

	for (i = 0; i < k; i++)
	{
		list[start + i] = tmp[i];
	}

	delete[] tmp;
}

//從上往下
void Merge_Sort_Up2down(int list[], int start, int end)
{
	if (list == NULL || start >= end)
	{
		return;
	}
	int mid = (end + start) / 2;
	Merge_Sort_Up2down(list, start, mid);//左半邊
	Merge_Sort_Up2down(list, mid + 1, end);//右半邊

	Merge(list, start, mid, end);
}

//從下往上
void MergeGroups(int list[], int len, int gap)
{
	int i;
	int twolen = 2 * gap;//兩個相鄰子數組長度

	//每兩個相鄰子數組合並排序
	for (i = 0; i + twolen - 1 < len; i += twolen)
	{
		Merge(list, i, i + gap - 1, i + twolen - 1);
	}

	if (i + gap - 1 < len - 1)//剩餘一個子數組沒有配對
	{
		Merge(list, i, i + gap - 1, len - 1);
	}
}

void Merge_Sort_Down2up(int list[], int len)
{
	int n;
	if (list == NULL || len <= 0)
	{
		return;
	}
	for (n = 1; n < len; n++)
	{
		MergeGroups(list, len, n);
	}
}

int main()
{
	int list[] = { 12, 5, 4, 6, 7, 6, 1 };

	Merge_Sort_Up2down(list, 0, sizeof(list) / sizeof(int)-1);

	for (int i = 0; i < sizeof(list) / sizeof(int); i++)
	{
		cout << list[i] << endl;
	}
}

歸併排序是一種穩定的排序方法,在最好、最壞、平均情況下的時間複雜度:O(n\log n),空間複雜度爲O(1)

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章