数据结构快速排序

目录

快速排序的前世今生

快速排序核心思想

挖坑法代码

挖坑法动图演示

全部代码


快速排序的前世今生

如果将来你工作后,你的老板要让你写个排序算法,而你会的算法中竟然没有快速排序,我想你还是不要声张,偷偷去把快速排序算法找来敲进电脑,这样不至于被大伙儿嘲笑。

快速排序算法最早由图灵奖获得者Tony Hoare 设计出来的,是上世纪最伟大的计算机科学家之一。更牛的是,我们现在要学习的这个快速排序算法,被列为20世纪十大算法之一。我们这些学编程的还有什么理由不去学习它呢?

快速排序是冒泡排序的升级版,它们都属于交换类排序。它是通过不断比较和移动交换来实现排序的,只不过它的实现,增大了记录的比较和移动的距离,将较大的直接从前面移动到后面去,较小的直接从后面移动到前面,从而减少了移动的次数和比较的次数。

快速排序核心思想

通过一趟排序将待排序记录分割成独立的两部分,其中一部分均比另一部分小,再分别对这两部分继续进行排序,从而达到有序。

挖坑法代码


//挖坑法
int PortSort2(int* a, int left, int right)
{
	int MidIndex = GetMid(a, left, right);
	Swap(&a[right], &a[MidIndex]);
	//假设这个位置是坑
	int key = a[right];
	while (left < right)
	{
		//左边找到比key大的就填到右边的坑,左边形成新的坑
		while (left < right && a[left] <= key)
		{
			++left;
		}
		a[right] = a[left];
		//右边找到比key小的就填到左边的坑,右边形成新的坑
		while (left < right && a[right] >= key)
		{
			--right;
		}
		a[left] = a[right];
	}
	//下标相遇了就把假设的中位数放入
	a[left] = key;
	return left;//返回中位数下标
}


//快速排序
void QuickSort1(int* a, int left, int right)
{
	assert(a);
	if (left >= right)//递归结束条件,两下标相遇
		return;
	//找出第一个中位数
	int div = PortSort2(a, left, right);
	//Printary(a + left, right - left + 1);
	//printf("[%d %d] %d [%d %d]\n", left, div-1 , div ,div+1, right);
	//下一次递归的范围:左边[left,div-1],div,右边[div+1,right]
	//对中位数左边递归
	QuickSort1(a, left, div - 1);
	//对中位数右边递归
	QuickSort1(a, div + 1, right);
}

挖坑法动图演示

数据结构快速排序_第1张图片

全部代码

#include
#include
#include
//交换函数
void Swap(int* p1, int* p2)
{
	int temp = *p1;
	*p1 = *p2;
	*p2 = temp;
}
//打印函数
void Printary(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
}
//三数取中,保证不是最大也不是最小
int GetMid(int* a, int begin, int end)
{
	int MidIndex = (begin + end) / 2;
	if (a[begin] > a[MidIndex])
	{
		if (a[MidIndex] > a[end])
			return MidIndex;
		else if (a[end] > a[begin])
			return begin;
		else
			return end;
	}
	else
	{
		//a[begin] < a[MidIndex]
		if (a[MidIndex] < a[end])
			return MidIndex;
		else if (a[begin] > a[end])
			return begin;
		else
			return end;
	}
}
//挖坑法
int PortSort2(int* a, int left, int right)
{
	int MidIndex = GetMid(a, left, right);
	Swap(&a[right], &a[MidIndex]);
	//假设这个位置是坑
	int key = a[right];
	while (left < right)
	{
		//左边找到比key大的就填到右边的坑,左边形成新的坑
		while (left < right && a[left] <= key)
		{
			++left;
		}
		a[right] = a[left];
		//右边找到比key小的就填到左边的坑,右边形成新的坑
		while (left < right && a[right] >= key)
		{
			--right;
		}
		a[left] = a[right];
	}
	//下标相遇了就把假设的中位数放入
	a[left] = key;
	return left;//返回中位数下标
}

//快速排序
void QuickSort1(int* a, int left, int right)
{
	assert(a);
	if (left >= right)//递归结束条件,两下标相遇
		return;
	//找出第一个中位数
	int div = PortSort2(a, left, right);
	//Printary(a + left, right - left + 1);
	//printf("[%d %d] %d [%d %d]\n", left, div-1 , div ,div+1, right);
	//下一次递归的范围:左边[left,div-1],div,右边[div+1,right]
	//对中位数左边递归
	QuickSort1(a, left, div - 1);
	//对中位数右边递归
	QuickSort1(a, div + 1, right);
}


//快速排序
void TestQuickSort()
{
	int a[] = { 6,1,2,7,9,3,4,5,10,8 };
	Printary(a, sizeof(a) / sizeof(a[0]));
	QuickSort1(a, 0, sizeof(a) / sizeof(a[0]) - 1);
	Printary(a, sizeof(a) / sizeof(a[0]));
}

int main()
{
	TestQuickSort();
	return 0;
}

排序结果示例

数据结构快速排序_第2张图片

你可能感兴趣的:(数据结构,排序算法,算法)