快速排序

1. 冒泡排序(稳定的)

     首先将第一个记录的关键字与第二个记录的关键字比较,按照升序或者降序,将两个记录交换。然后比较第二个记录和第三个记录的关键字。依次类推,直到第n-1个记录和第n个记录的关键字进行比较。上述过程即称为一趟排序,第一趟排序完后,某个记录的关键字最小或者最大的排列到整个序列的前面后者后面。然后以此类推,对n-1个元素组成的序列进行同样的排序操作..........经过n-1趟排序后,整个序列便确定了顺序。

void BubbleSort1(int * pArry, int ilen)
{
	int i, j;
	int temp;
	for (i = 0; i < ilen - 1; i++)               //排序趟数,共n-1趟
	{
		for (j =0 ; j < ilen - 1 - i; j++)  //每趟排序出关键字最小的记录,并位于待排子序列的首位
		{
			if (pArry[j] > pArry[j + 1])
			{
				temp = pArry[j];
				pArry[j] = pArry[j + 1];
				pArry[j + 1] = temp;
			}
		}
	}
}

     改进型的排序算法:增加一个布尔变量,记录排序过程中是否存在数据交换,若在某趟排序过程结束后都不存在数据交换,则表明此时待排序序列已经是有序的,可忽略剩余的排序趟次。

void bubbleSort2(int * pArry, int n)
{
	bool bExchange;
	for (int i = 0; i < n - 1; i++)              //排序趟次
	{
		bExchange = false;
		for (int j = 0; j < n - 1 - i; j++)  //每趟两两比较次数
		{
			if (pArry[j] > pArry[j + 1])
			{
				int temp = pArry[j];
				pArry[j] = pArry[j + 1];
				pArry[j + 1] = temp;
				bExchange = true;
			}
		}
		if (!bExchange)
		{
			return ;
		}
	}
}

冒泡排序算法的时间复杂度:最好的时间复杂度为O(n),最坏为O(n^2)。


2. 快速排序

   基本思想:从待排序的n个数据元素中任意选取一个元素Ri(通常选取无序序列的第一个元素)作基准,调整序列中各个元素的位置,使排在Ri前面的元素的排序码都小于Ri.key,排在Ri后面的元素的排序码都大于Ri.key。通常称这个过程为一次快速排序。

  在一次快速排序中,确定了Ri最终在序列中的排列位置,同时将剩下的数据元素分成了两个子序列,对两个子序列再分别进行快速排序,如此重复下去,当各个子序列的长度为1时,全部元素排序完成。(递归调用过程)

void QuickSort(int * pArry, int ileft, int iright)
{
	int i = ileft;  //指向待排序序列的最左端
	int j = iright; //指向待排序序列的最右端
	int iKey =pArry[ileft];

	while (i < j)
	{
		while (i < j && iKey <= pArry[j])  //首先从右往左扫描,若扫描到的记录大于或等于iKey,指针j往左移 
		{                                  //为什么首先要从右扫描起走?因为若首先从左扫描,如果找到比ikey值大的关键字,将该记录置于何处??
			--j;                       //首先从右扫描就不存在这个问题,若扫描到比ikey小得关键字,则将其与指针i指向的记录交换,
		}                                  //因为初始时指针i指向的记录已经保存于iKey。
		if (i < j)                         
		{
			pArry[i] = pArry[j];           //否则将该记录与指针i指向的记录交换, 指针i往右移。
			i++;
		}

		while ( i < j && iKey >= pArry[i])  //从左往右扫描,若扫描到的记录关键字小于或等于iKey,指针i往右移 
		{
			i++;
		}
		if (i < j)
		{
			pArry[j] = pArry[i];          //否则将该记录与指针j指向的记录交换, 指针j往左移。  
			--j;
		}
	}
	pArry[i] = iKey;                      //最后循环结束后,确定了iKey(即第一个记录)在序列中的位置

	if (ileft < i)
	{
		QuickSort(pArry, ileft, i - 1);    //递归对左子序列进行快排
	}
	if (i < iright)
	{
		QuickSort(pArry, i + 1, iright);   //递归对右子序列进行快排
	}
}

     快速排序的平均时间为T(n) = knlog2(n) ,其中n为排序序列中记录的个数,k为某个常数。就平均时间而言,快速排序是目前被认为最好的一种内部排序方法。在所有同量级O(nlogn)的排序方法中,其平均性能最好。

     若初始记录序列按关键字有序或者基本有序,快速排序将蜕化为起泡排序,其时间复杂度为O(n^2)。

      快速排序是不稳定的排序,并且对于同一待排序序列,若选取的基准元素不同的话,其排序速度可能不同。如果选择的基准排序恰好是序列中所有元素的中位数,则划分的前后两个子序列的元素数目近乎相等,这时快速排序最快。

    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值