排序(三)冒泡排序与快速排序(C语言实现)

冒泡排序与快速排序都属于交换排序,其中冒泡排序也是十分的出名,实现起来也比较简便,下面一一介绍这两种排序。

1、冒泡排序

冒泡排序的意思就是将最大的数沉底,或者最小的数提到最前面来,之后再抛开这个数找次大或此次小的数进行循环,这个过程比较像泡泡从小变大的过程因此称作冒泡排序。

排序(三)冒泡排序与快速排序(C语言实现)_第1张图片

代码实现:

void BubbleSort(int* a, int n)
{
	assert(a);//断言判断
	for (int j = 0; j < n; j++)
	{
		int flag = 0;//用于提高循环效率,如果提前排序完成,则不用再继续进行比较
                     //置flag为1后便可跳出循环
		for (int i = 1; i < n - j; i++)
		{
			if (a[i - 1] > a[i])
				Swap(&a[i - 1], &a[i]);
			flag = 1;
		}
		if (flag == 0)
			break;
	}
}

2、快速排序

快速排序正如其名,效率非常的快,但是算法比较复杂,要求使用递归思想。

我们先来看单趟的排序过程:

首先要选定一个值为key(一般都选择数组最左端或最右端的值),让所有比key小的值在key左边,比key大的值在key右边(以下为升序思路)

排序(三)冒泡排序与快速排序(C语言实现)_第2张图片

 这里取最左端的值为key,接下来就是先从右边开始依次遍历数组寻找比key小的数

排序(三)冒泡排序与快速排序(C语言实现)_第3张图片

 此时right所在下标的值比key大,则再从左边开始找比key大的数

排序(三)冒泡排序与快速排序(C语言实现)_第4张图片

 交换left与right所对应的值

排序(三)冒泡排序与快速排序(C语言实现)_第5张图片

 之后再重复以上步骤直到left与right相遇为止

排序(三)冒泡排序与快速排序(C语言实现)_第6张图片

最后将left所对应的值与key交换(如果选取左边为key一定要从右边开始找,这样可以保证left最后所在位置一定比key小或等于key)

排序(三)冒泡排序与快速排序(C语言实现)_第7张图片

这时整个数组被分为三个区间其所对应的下标分别是[begin,key-1]key[key+1,end],其中key所在位置不用再变化,而要分别对左右两个区间再进行单趟快速排序

左:

排序(三)冒泡排序与快速排序(C语言实现)_第8张图片

右:

排序(三)冒泡排序与快速排序(C语言实现)_第9张图片

因为取的数据比较巧,也只花了一次就完成排序了,没有体验出一个递归的过程,不过我们可以思考如果这一次排完还是无序便又要拆分成左右区间继续排序,直到区间只剩一个数或者不存在为止。

那么用代码来实现一下:

void QuickSort(int* a, int begin, int end)
{
	//当区间只有一个值或不存在则不需要再处理
	if (begin >= end)
	{
		return;
	}
	int left = begin;
	int right = end;
	int key = left;

	while (left < right)
	{
		//右边先走,找小
		while (left < right && a[right] >= a[key])//这里是第一个判断条件是防止left不动,right一直向左走越界的情况
											   //第二个判断条件的等于号一定不能少,如果左右都与key相等会死循环
		{
			right--;
		}
		//左边再走,找大
		while (left < right && a[left] <= a[key])
		{
			left++;
		}
		Swap(&a[right], &a[left]);
	}
	Swap(&a[left], &a[key]);//key取左边,右边先走一定能保证结束循环后left所在位置的值比key小
	key = left;
	//[begin,key-1]key[key+1,end],此时需要让key左右区间分别有序
	QuickSort(a, begin, key - 1);
	QuickSort(a, key + 1, end);//递归思想
}

你可能感兴趣的:(c语言,排序算法)