快速排序—C语言

快速排序(Quicksort)是对冒泡排序的一种改进。快速排序由C. A. R. Hoare在1962年提出。

快速排序的基本思想是:

通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法

对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

固定选取基准法

例如:对   49        38       65       97       76       13        27   进行排序。

  1. 将49定为基准,low和high分别代表第一个下表和最后一个数字的下标。天麻片为49
  2. 从high开始向前搜索,即由后开始向前搜索,找到第一个小于tmp的值,两者交换;
  3. 从Iow开始向后搜索,即由前开始向后搜索,找到第一个大于tmp的值,两者交换;

第一次排序之后的结果为 27        38       65       97       76       13        49

第二次排序之后的结果为 27        38       49       97       76       13        65

第三次排序之后的结果为27        38       13       97       76       49        65

第四次排序之后的结果是27        38       13       49       76       97        65

此时再执行第三不的时候就发现low = high,从而结束一躺快速排序,那么经过一躺快速排序之后的结果是:

27        38       13       49       76       97        65,即所以大于49的数全部在49的后面,所以小于49的数全部在49的前面。

之后进行递归调用分别对前面一部分和后面一部分进行类似的快速排序,从而完成全部数据序列的快速排序,最后把此数据序列

变成一个有序的序列。

int Partion(int *arr,int low,int high)//固定位置选取基准法
{
	int tmp = arr[low];
	while(low < high) 
	{
		while(low < high && arr[high] > tmp) 
		{
			high--;
		}
		if(low >= high)
		{
			break;
		}
		else 
		{
			arr[low] = arr[high];
		}
		while(low < high && arr[low] < tmp) 
		{
			low++;
		}
		if(low >= high)
		{
			break;
		}
		else 
		{
			arr[high] = arr[low];
		}
	}
	arr[low] = tmp;
	return low;
}
void Quick(int *arr,int start,int end)
{
	int par = Partion(arr,start,end); 
	if(par > start+1)
	{
		Quick(arr,start,par-1);
	} 
	if(par < end-1)
	{
		Quick(arr,par+1,end);
	}
}


void QuickSort(int *arr,int len)
{
	Quick(arr,0,len-1);
}

void Show(int *arr,int len)
{
	for(int i = 0;i  < len;i++) 
	{
		printf("%d ",arr[i]);
	}
	printf("\n");
}

int main()
{
	int arr[] = {1,32,0,76,45,2,7,9,4,5};
	int len = sizeof(arr)/sizeof(arr[0]);
	QuickSort(arr,len);
	Show(arr,len);
	return 0;
}

非递归实现快速排序

void QuickSort(int *arr,int len)
{
	int tmpSize = (int)log((double)len)/log((double)2);
	int *stack = (int *)malloc(sizeof(int)*tmpSize*2);//
	assert(stack != NULL);
	int top = 0;//数组的下标
	int low = 0;
	int high = len-1;
	int par = Partion(arr,low,high);//第一次找完基准
	if(par > low +1)
	{
		stack[top++] = low;
		stack[top++] =par-1;
	}
	if(par < high-1) 
	{
		stack[top++] = par+1;
		stack[top++] =high;
	}
	while(top > 0)//栈不为空
	{
		high = stack[--top];
		low = stack[--top];
		par = Partion(arr,low,high);//找完基准
		if(par > low +1)
		{
			stack[top++] = low;
			stack[top++] =par-1;
		}
		if(par < high-1) 
		{
			stack[top++] = par+1;
			stack[top++] =high;
		}

	}
	free(stack);
	stack = NULL;
}

随机选取基准法

在待排序列是部分有序时,固定选取枢轴使快排效率底下,要缓解这种情况,就有了随机选取基准法。取待排序列中任意一个元素作为基准,这样排序会加快一些。

void Swap(int *arr,int start,int end)
{
	int tmp = arr[start];
	arr[start] = arr[end];
	arr[end] = tmp;
}

三分取中法

void SelectPivotMedianOfThree(int *arr,int low,int high) 
{
	int mid = (high-low)/2+low;
	if(arr[mid] > arr[low])
	{
		Swap(arr,mid,low);
	}
	if(arr[low] > arr[high]) 
	{
		Swap(arr,low,high);
	}
	if(arr[mid] > arr[high])
	{
		Swap(arr,mid,high);
	}
}
发布了35 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_41078889/article/details/84317139
今日推荐