1. 程式人生 > >歸併排序與快速排序

歸併排序與快速排序

歸併排序

歸併的思想在於先分後排

“先分”:把整個序列劃分為一個一個單段(O(logn))

“後排”:將相鄰段內資料按照順序放入新的陣列,最後再將新陣列的資料放回原陣列(O(n))

由此總的時間複雜度為二者乘積=O(n*logn)

Code

#include <iostream>

using namespace std;

const int maxn = 10050;

int a[maxn];

void Merge(int left, int right)
{
	int *b = new int [right - left + 5];
	int mid = (left + right) / 2;
	int i = left, j = mid, k = 0;
	while (i < mid && j < right) b[k++] = a[i] < a[j] ? a[i++] : a[j++];

	while (i < mid) b[k++] = a[i++];
	while (j < right) b[k++] = a[j++];

	for (int c = 0; c < k; c++) a[left + c] = b[c];
}

void MergeSort(int left, int right)
{
	if (right - left > 1)
	{
		int mid = (left + right) / 2;
		MergeSort(left, mid);
		MergeSort(mid, right);
		Merge(left, right);
	}
}


void print(int n)
{
	for (int i = 0; i < n; i++)
	{
		if (i) cout << " ";
		cout << a[i];
	}
	cout << endl;
}

int main()
{
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) cin >> a[i];
	MergeSort(0, n);
	print(n);
	return 0;
}

 

快速排序

快速排序的思想與歸併排序剛好相反,在於先排序,後分治

“先排序”:選定第一個元素作為基準,保證其插入一個合適的位置,使得該元素左邊的元素都比其小,右邊的都比其大;

“後分治”:在於將上一次選定的元素之前和之後的序列進行重新排序(記住是上一次確定位置的元素,而不是中點元素)

Code

#include <iostream>

using namespace std;

const int maxn = 10050;

int a[maxn];


void quicksort(int left, int right)
{
	if (right - left > 1)
	{
		int i = left, j = right - 1;
		int temp = a[i];

		do
		{
			while (i < j && a[j] > temp) j--;
			if (i < j)
			{
				a[i] = a[j];
				i++;
			}

			while (i < j && a[i] < temp) i++;
			if (i < j)
			{
				a[j] = a[i];
				j--;
			}

		} while (i != j);

		a[i] = temp;

		quicksort(left, i);
		quicksort(i + 1, right);
	}
}


void print(int n)
{
	for (int i = 0; i < n; i++)
	{
		if (i) cout << " ";
		cout << a[i];
	}
	cout << endl;
}

int main()
{
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) cin >> a[i];
	quicksort(0, n);
	print(n);
	return 0;
}