[プログラミング]データ構造の概要:クイックソート(3種類の再帰、1種類の非再帰)マージソート(再帰、非再帰)

クイックソート(3種類の再帰)

// Pointer排序——快速排序
int ReferencePositionPointer(int* arr, int begin, int end)
{
    
    
	int prev = begin;
	int cur = begin + 1;
	int refvalue = arr[begin];
	while (cur <= end)
	{
    
    
		if (arr[cur] < refvalue && ++prev != cur)
		{
    
    
			Swap(arr, prev, cur);
		}
		cur++;
	}
	Swap(arr, begin, prev);
	return prev;
}

void QuickSort(int* arr, int begin, int end)
{
    
    
	if (begin >= end)
		return;
	int refposition = ReferencePositionPointer(arr, begin, end);
	QuickSort(arr, begin, refposition - 1);
	QuickSort(arr, refposition + 1, end);
}
// Hoare排序——快速排序
int ReferencePositionHoare(int* arr, int begin, int end)
{
    
    
	int mid = midposition(arr, begin, end);
	Swap(arr, mid, begin);
	int refvalue = arr[begin];
	int refposition = begin;
	while (begin < end)
	{
    
    
		while (begin < end && arr[end] >= refvalue)
		{
    
    
			end--;
		}
		arr[begin] = arr[end];
		while (begin < end && arr[begin] <= refvalue)
		{
    
    
			begin++;
		}
		arr[end] = arr[begin];
	}
	arr[begin] = refvalue;
	return begin;
}

void QuickSort(int* arr, int begin, int end)
{
    
    
	if (begin >= end)
		return;
	int refposition = ReferencePositionHoare(arr, begin, end);
	QuickSort(arr, begin, refposition - 1);
	QuickSort(arr, refposition + 1, end);
}
// 三数取中法——快速排序
int midposition(int* arr, int begin, int end)
{
    
    
	int mid = begin + (end - begin) / 2;
	if (arr[begin] > arr[mid])
	{
    
    
		if (arr[mid] > arr[end])
		{
    
    
			return mid;
		}
		else if (arr[begin] > arr[end])
		{
    
    
			return end;
		}
		else
			return begin;

	}
	else
	{
    
    
		if (arr[end] > arr[mid])
			return mid;
		else if (arr[begin] > arr[mid])
			return begin;
		else
			return end;
	}
}


// 获取基准位置——快速排序
int ReferencePosition(int* arr, int begin, int end)
{
    
    
	int mid = midposition(arr, begin, end);
	Swap(arr, mid, begin);
	int refvalue = arr[begin];
	int refposition = begin;
	while (begin < end)
	{
    
    
		while (begin < end && arr[end] >= refvalue)
		{
    
    
			end--;
		}
		while (begin < end && arr[begin] <= refvalue)
		{
    
    
			begin++;
		}
		Swap(arr, begin, end);
	}
	Swap(arr, refposition, begin);
	return begin;
}

// 快速排序法 O(n^2)
// 数据有序时,可能会出现栈溢出
// 优化方法:三数取中法
// 优化后 O(nlogn) 相当于栈的调用层数
void QuickSort(int* arr, int begin, int end)
{
    
    
	if (begin >= end)
		return;
	int refposition = ReferencePosition(arr, begin, end);
	QuickSort(arr, begin, refposition - 1);
	QuickSort(arr, refposition + 1, end);
}

クイックソート(非再帰的)

// 非递归快速排序——保存每个子区间——优点:不会导致栈溢出
// 顺序表实现
int ReferencePositionNonRecursion(int* arr, int n)
{
    
    
	seqList sq;
	initseqList(&sq);
	seqListPushBack(&sq, n - 1);
	seqListPushBack(&sq, 0);
	while (!seqListEmpty(&sq))
	{
    
    
		int left = seqListBack(&sq);
		seqListPopBack(&sq);
		int right = seqListBack(&sq);
		seqListPopBack(&sq);

		int div = ReferencePosition(arr, left, right);

		if (left < div - 1)
		{
    
    
			seqListPushBack(&sq, div - 1);
			seqListPushBack(&sq, left);
		}
		if (div + 1 < right)
		{
    
    
			seqListPushBack(&sq, right);
			seqListPushBack(&sq, div + 1);
		}
	}
}
// 非递归快速排序——保存每个子区间——优点:不会导致栈溢出
// 队列实现
void ReferencePositionNonRecursion(int* arr, int n)
{
    
    
	Queue sq;
	QueueInit(&sq);
	QueuePush(&sq, 0);
	QueuePush(&sq, n - 1);
	while (!QueueEmpty(&sq))
	{
    
    
		int left = QueueFront(&sq);
		QueuePop(&sq);
		int right = QueueFront(&sq);
		QueuePop(&sq);

		int div = ReferencePosition(arr, left, right);

		if (left < div - 1)
		{
    
    
			QueuePush(&sq, left);
			QueuePush(&sq, div - 1);
		}
		if (div + 1 < right)
		{
    
    
			QueuePush(&sq, div + 1);
			QueuePush(&sq, right);
		}
	}
}

更新中

おすすめ

転載: blog.csdn.net/m0_46613023/article/details/114357672