【Practical】归并排序

递归版本.

#include <iostream>

using namespace std;

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

void Swap(int *x, int *y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}

void BubbleSort1(int *a, int n)
{
	// Judge.
	if (n < 2)
	{
		return;
	}

	int tmp = 0;

	for (int i = n - 1; i > 0; --i)
	{
		bool isSwap = false;
		for (int j = 0; j < n - 1; ++j)
		{
			if (a[j] > a[j + 1])
			{
				tmp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = tmp;
				isSwap = true;
			}
		}
		if (isSwap == false)
		{
			return;
		}
	}
}

void BubbleSort2(int *a, int n)
{
	if (n < 2)
	{
		return;
	}

	bool isSwap = false;

	int tmp = 0;
	for (int j = 0; j < n - 1; ++j)
	{
		if (a[j] > a[j + 1])
		{
			tmp = a[j];
			a[j] = a[j + 1];
			a[j + 1] = tmp;
			isSwap = true;
		}
	}

	if (isSwap == false)
	{
		return;
	}

	BubbleSort2(a, --n);
}

void SelectionSort1(int *a,int n)
{
	if (n < 2)
	{
		return;
	}

	int left = 0;
	int right = n - 1;

	while (left < right)
	{
		int minpos = left;
		int maxpos = left;

		for (int i = left + 1; i <= right; ++i)
		{
			if (a[i] < a[minpos])
			{
				minpos = i;
			}
			else if (a[i] > a[maxpos])
			{
				maxpos = i;
			}
		}

		if (minpos != left)
		{
			Swap(&a[minpos], &a[left]);
		}

		if (maxpos == left)
		{
			maxpos = minpos;
		}

		if (maxpos != right)
		{
			Swap(&a[maxpos], &a[right]);
		}

		++left;
		--right;
	}
}

void SelectionSort2(int *a, int n)
{
	if (n < 2)
	{
		return;
	}

	int minpos = 0;
	int maxpos = 0;
	for (int j = 1; j < n; ++j)
	{
		if (a[j] < a[minpos])
		{
			minpos = j;
		}
		else if (a[j] > a[maxpos])
		{
			maxpos = j;
		}
	}

	if (minpos != 0)
	{
		Swap(&a[minpos], &a[0]);
	}

	if (maxpos == 0)
	{
		maxpos = minpos;
	}

	if (maxpos != n - 1)
	{
		Swap(&a[maxpos], &a[n - 1]);
	}

	SelectionSort2(a + 1, n - 2);
}

void InsertionSort(int *a, int n)
{
	if (n < 2)
	{
		return;
	}

	for (int i = 1; i < n; ++i)
	{
		int tmp = a[i];
		int pos = 0;
		for (int j = i - 1; j >= 0; --j)
		{
			if (a[j] <= tmp)
			{
				pos = j + 1;
				break;
			}
			a[j + 1] = a[j];
		}
		a[pos] = tmp;
	}
}

void ShellSort(int *a, int n)
{
	// int cnt = 0;
	if (n < 2)
	{
		return;
	}

	int h = 1;
	while (h < n / 2)
	{
		h = 2 * h + 1;
	}

	while (h >= 1)
	{
		for (int i = h; i < n; ++i)
		{
			for (int j = i; j >= h && a[j - h] > a[j]; j = j - h)
			{
				Swap(&a[j], &a[j - h]);
				// ++cnt;
			}
		}
		h = h / 2;
	}
	// cout << cnt << endl;
}

int Pivot(int *a, int left, int right)
{
	int mid = (right + left) / 2;

	if (a[mid] >= a[left])
	{
		if (a[mid] >= a[right])
		{
			return a[left] >= a[right] ? left : right;
		}
		else
		{
			return mid;
		}
	}
	else
	{
		if (a[mid] <= a[right])
		{
			return a[right] <= a[left] ? right : left;
		}
		else
		{
			return mid;
		}
	}
}

int Partition(int *a, int left, int right)
{
	// int pivot = a[left];
	
	int p = Pivot(a, left, right);
	int pivot = a[p];
	Swap(&a[p], &a[left]);

	int i = left + 1;
	int j = right;

	while (true)
	{
		while (a[i] < pivot)
		{
			++i;
			if (i == right)
			{
				break;
			}
		}

		while (a[j] > pivot)
		{
			--j;
			if (j == left)
			{
				break;
			}
		}

		if (i >= j)
		{
			break;
		}

		Swap(&a[i], &a[j]);

	}

	Swap(&a[j], &a[left]);

	return j;
}

int LomutoPartition(int *a, int left, int right)
{
	// int pivot = a[left];

	int p = Pivot(a, left, right);
	int pivot = a[p];
	Swap(&a[p], &a[left]);

	int s = left;
	
	for (int i = left + 1; i <= right; ++i)
	{
		if (a[i] < pivot)
		{
			++s;
			Swap(&a[i], &a[s]);
		}
	}

	Swap(&a[left], &a[s]);

	return s;
}

int HolePartition(int* a, int left, int right)
{
	// int pivot = a[left];

	int p = Pivot(a, left, right);
	int pivot = a[p];
	Swap(&a[p], &a[left]);

	int i = left;
	int j = right;

	while (i < j)
	{
		while (a[j] > pivot)
		{
			--j;
			if (j == i)
			{
				break;
			}
		}

		a[i] = a[j];

		while (a[i] < pivot)
		{
			++i;
			if (i == j)
			{
				break;
			}
		}

		a[j] = a[i];
	}

	a[j] = pivot;
	return j;
}

void QuickSort(int *a, int left, int right)
{
	if (left >= right)
	{
		return;
	}

	// int pivot = Partition(a, left, right);
	// int pivot = LomutoPartition(a, left, right);
	int pivot = HolePartition(a, left, right);

	QuickSort(a, left, pivot - 1);
	QuickSort(a, pivot + 1, right);

}

void QuickSort(int* a, int n)
{
	if (n < 2)
	{
		return;
	}

	QuickSort(a, 0, n - 1);

}

void Merge(int *a, int left, int mid, int right)
{
	int* copy = new int[right - left + 1];
	for (int i = 0; i < right - left + 1; ++i)
	{
		copy[i] = a[i + left];
		// cout << copy[i] << " ";
	}
	// cout << endl;

	int i = 0;
	int j = mid - left + 1;

	int k = left;
	while (i != mid - left + 1 && j != right - left + 1)
	{
		if (copy[i] <= copy[j])
		{
			a[k] = copy[i];
			++k;
			++i;
		}
		else
		{
			a[k] = copy[j];
			++k;
			++j;
		}
	}

	if (i == mid - left + 1)
	{
		for (j; j <= right - left; ++j)
		{
			a[k] = copy[j];
			++k;
		}
	}
	else if (j == right - left + 1);
	{
		for (i; i <= mid - left; ++i)
		{
			a[k] = copy[i];
			++k;
		}
	}

	delete copy;
}

void Mergesort(int *a, int left, int right)
{
	if (left >= right)
	{
		return;
	}

	int mid = (left + right) / 2;

	Mergesort(a, left, mid);
	Mergesort(a, mid + 1, right);
	Merge(a, left, mid, right);
}

void Mergesort(int *a, int n)
{
	if (n < 2)
	{
		return;
	}

	Mergesort(a, 0, n - 1);
}

int main()
{
	int arr[] = { 44,3,38,5,47,15,36,26,27,2,46,4,19,50,48 };
	int len = sizeof(arr) / sizeof(int);

	Display(arr, len);

	// BubbleSort1(arr, len);
	// BubbleSort2(arr, len);
	// SelectionSort1(arr, len);
	// SelectionSort2(arr, len);
	// InsertionSort(arr, len);
	// ShellSort(arr, len);
	// QuickSort(arr, len);

	Mergesort(arr, len);

	Display(arr, len);

	return 0;
}

循环版本.

#include <iostream>

using namespace std;

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

void Swap(int *x, int *y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}

void BubbleSort1(int *a, int n)
{
	// Judge.
	if (n < 2)
	{
		return;
	}

	int tmp = 0;

	for (int i = n - 1; i > 0; --i)
	{
		bool isSwap = false;
		for (int j = 0; j < n - 1; ++j)
		{
			if (a[j] > a[j + 1])
			{
				tmp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = tmp;
				isSwap = true;
			}
		}
		if (isSwap == false)
		{
			return;
		}
	}
}

void BubbleSort2(int *a, int n)
{
	if (n < 2)
	{
		return;
	}

	bool isSwap = false;

	int tmp = 0;
	for (int j = 0; j < n - 1; ++j)
	{
		if (a[j] > a[j + 1])
		{
			tmp = a[j];
			a[j] = a[j + 1];
			a[j + 1] = tmp;
			isSwap = true;
		}
	}

	if (isSwap == false)
	{
		return;
	}

	BubbleSort2(a, --n);
}

void SelectionSort1(int *a,int n)
{
	if (n < 2)
	{
		return;
	}

	int left = 0;
	int right = n - 1;

	while (left < right)
	{
		int minpos = left;
		int maxpos = left;

		for (int i = left + 1; i <= right; ++i)
		{
			if (a[i] < a[minpos])
			{
				minpos = i;
			}
			else if (a[i] > a[maxpos])
			{
				maxpos = i;
			}
		}

		if (minpos != left)
		{
			Swap(&a[minpos], &a[left]);
		}

		if (maxpos == left)
		{
			maxpos = minpos;
		}

		if (maxpos != right)
		{
			Swap(&a[maxpos], &a[right]);
		}

		++left;
		--right;
	}
}

void SelectionSort2(int *a, int n)
{
	if (n < 2)
	{
		return;
	}

	int minpos = 0;
	int maxpos = 0;
	for (int j = 1; j < n; ++j)
	{
		if (a[j] < a[minpos])
		{
			minpos = j;
		}
		else if (a[j] > a[maxpos])
		{
			maxpos = j;
		}
	}

	if (minpos != 0)
	{
		Swap(&a[minpos], &a[0]);
	}

	if (maxpos == 0)
	{
		maxpos = minpos;
	}

	if (maxpos != n - 1)
	{
		Swap(&a[maxpos], &a[n - 1]);
	}

	SelectionSort2(a + 1, n - 2);
}

void InsertionSort(int *a, int n)
{
	if (n < 2)
	{
		return;
	}

	for (int i = 1; i < n; ++i)
	{
		int tmp = a[i];
		int pos = 0;
		for (int j = i - 1; j >= 0; --j)
		{
			if (a[j] <= tmp)
			{
				pos = j + 1;
				break;
			}
			a[j + 1] = a[j];
		}
		a[pos] = tmp;
	}
}

void ShellSort(int *a, int n)
{
	// int cnt = 0;
	if (n < 2)
	{
		return;
	}

	int h = 1;
	while (h < n / 2)
	{
		h = 2 * h + 1;
	}

	while (h >= 1)
	{
		for (int i = h; i < n; ++i)
		{
			for (int j = i; j >= h && a[j - h] > a[j]; j = j - h)
			{
				Swap(&a[j], &a[j - h]);
				// ++cnt;
			}
		}
		h = h / 2;
	}
	// cout << cnt << endl;
}

int Pivot(int *a, int left, int right)
{
	int mid = (right + left) / 2;

	if (a[mid] >= a[left])
	{
		if (a[mid] >= a[right])
		{
			return a[left] >= a[right] ? left : right;
		}
		else
		{
			return mid;
		}
	}
	else
	{
		if (a[mid] <= a[right])
		{
			return a[right] <= a[left] ? right : left;
		}
		else
		{
			return mid;
		}
	}
}

int Partition(int *a, int left, int right)
{
	// int pivot = a[left];
	
	int p = Pivot(a, left, right);
	int pivot = a[p];
	Swap(&a[p], &a[left]);

	int i = left + 1;
	int j = right;

	while (true)
	{
		while (a[i] < pivot)
		{
			++i;
			if (i == right)
			{
				break;
			}
		}

		while (a[j] > pivot)
		{
			--j;
			if (j == left)
			{
				break;
			}
		}

		if (i >= j)
		{
			break;
		}

		Swap(&a[i], &a[j]);

	}

	Swap(&a[j], &a[left]);

	return j;
}

int LomutoPartition(int *a, int left, int right)
{
	// int pivot = a[left];

	int p = Pivot(a, left, right);
	int pivot = a[p];
	Swap(&a[p], &a[left]);

	int s = left;
	
	for (int i = left + 1; i <= right; ++i)
	{
		if (a[i] < pivot)
		{
			++s;
			Swap(&a[i], &a[s]);
		}
	}

	Swap(&a[left], &a[s]);

	return s;
}

int HolePartition(int* a, int left, int right)
{
	// int pivot = a[left];

	int p = Pivot(a, left, right);
	int pivot = a[p];
	Swap(&a[p], &a[left]);

	int i = left;
	int j = right;

	while (i < j)
	{
		while (a[j] > pivot)
		{
			--j;
			if (j == i)
			{
				break;
			}
		}

		a[i] = a[j];

		while (a[i] < pivot)
		{
			++i;
			if (i == j)
			{
				break;
			}
		}

		a[j] = a[i];
	}

	a[j] = pivot;
	return j;
}

void QuickSort(int *a, int left, int right)
{
	if (left >= right)
	{
		return;
	}

	// int pivot = Partition(a, left, right);
	// int pivot = LomutoPartition(a, left, right);
	int pivot = HolePartition(a, left, right);

	QuickSort(a, left, pivot - 1);
	QuickSort(a, pivot + 1, right);

}

void QuickSort(int* a, int n)
{
	if (n < 2)
	{
		return;
	}

	QuickSort(a, 0, n - 1);

}

void Merge(int *a, int left, int mid, int right)
{
	int* copy = new int[right - left + 1];
	for (int i = 0; i < right - left + 1; ++i)
	{
		copy[i] = a[i + left];
		// cout << copy[i] << " ";
	}
	// cout << endl;

	int i = 0;
	int j = mid - left + 1;

	int k = left;
	while (i != mid - left + 1 && j != right - left + 1)
	{
		if (copy[i] <= copy[j])
		{
			a[k] = copy[i];
			++k;
			++i;
		}
		else
		{
			a[k] = copy[j];
			++k;
			++j;
		}
	}

	if (i == mid - left + 1)
	{
		for (j; j <= right - left; ++j)
		{
			a[k] = copy[j];
			++k;
		}
	}
	else if (j == right - left + 1);
	{
		for (i; i <= mid - left; ++i)
		{
			a[k] = copy[i];
			++k;
		}
	}

	delete copy;
}

void Mergesort(int *a, int left, int right)
{
	if (left >= right)
	{
		return;
	}

	int mid = (left + right) / 2;

	Mergesort(a, left, mid);
	Mergesort(a, mid + 1, right);
	Merge(a, left, mid, right);
}

void MergeSort1(int *a, int n)
{
	if (n < 2)
	{
		return;
	}

	Mergesort(a, 0, n - 1);
}

void MergeSort2(int *a, int n)
{
	if (n < 2)
	{
		return;
	}
	
	for (int iseg = 1; iseg < n; iseg = iseg * 2)
	{
		for (int left = 0; left < n; left = left + iseg * 2)
		{
			int right = (left + iseg * 2 - 1) > (n-1) ? (n-1) : (left + iseg * 2 - 1);

			int  mid = (left + right) / 2;

			Merge(a, left, mid, right);
		}
	}

}

int main()
{
	int arr[] = { 44,3,38,5,47,15,36,26,27,2,46,4,19,50,48 };
	int len = sizeof(arr) / sizeof(int);

	Display(arr, len);

	// BubbleSort1(arr, len);
	// BubbleSort2(arr, len);
	// SelectionSort1(arr, len);
	// SelectionSort2(arr, len);
	// InsertionSort(arr, len);
	// ShellSort(arr, len);
	// QuickSort(arr, len);
	// MergeSort1(arr, len);

	MergeSort2(arr, len);

	Display(arr, len);

	return 0;
}
上一篇:SpringBoot配置devtools实现热部署


下一篇:5 驱动开发常见问题解决