排序算法(二)--交换排序之起泡排序,快速排序

交换排序:

是借助交换进行排序的方法,其主要思想是:在待排序列中选两个记录,按关键码比较,如果反序则交换他们的位置.

起泡排序:基本思想:两两比较相邻元素的关键码,如果反序则交换,直到没有反序元素为止.
template<class T>
void BubbleSort(T array[], int nLen)
{
	int exchange = nLen - 1;
	int bound = exchange;
	while (exchange)
	{
		exchange = 0; // 每次循环前置exchange = 0;如果没有交换则退出.
		for (int i = 0; i<bound; i++)
		{
			if (array[i] > array[i+1])
			{
				exchange = i; // 记录交换的位置作为下次比较的结束点.
				int temp = array[i];
				array[i] = array[i+1];
				array[i+1] = temp;
			}
		}
	}
}
起泡排序最好情况下:序列为正序,进行了n-1次比较,不需要移动记录.时间复杂度为O(n);
最坏情况下,记录为反序,进行了n(n-1)/2次比较,移动次数为3(n-1)n/2,所以时间复杂度为O(n^2);
平均情况下,起泡排序与最坏情况同数量级.
起泡排序需要一个辅助空间,用来保存交换元素的暂存单元

起泡排序是一种稳定的算法.


快速排序是对起泡排序的一种改进,改进的着眼点是:在起泡排序中记录的比较和移动是在相邻位置进行的,记录每次比较和移动只能移动一个位置,所以总的比较和移动次数较多.在快速排序中,记录的比较和移动是从两端向中间进行的,关键码较小的记录一次就能从后面移动到前面,关键码较大的一次就能从前面移动到后面,从而减少了总的移动和比较次数.

快速排序又称分区交换排序,其基本思想是:选取一个轴值,即比较的基准,左侧记录关键码均小于等于轴值,右侧记录
均大于等于轴值,然后分别对上述两部分重复上述过程,直到整个序列有序.显然快速排序是一个递归过程.
快速排序一次划分算法伪代码:
将i和j分别指向待排序列最左记录与最右侧记录;
重复下述过程,直到i = j;
右侧扫描,j--,直到a[j]<a[i],交换a[j]与a[i],i++;
左侧扫描,直到a[i]>a[j],交换,j--;

循环结束,i = j,返回i的位置.


// 一次划分
template <class T>
int Partition(T array[], int nStart, int nEnd)
{
	int i = nStart;
	int j = nEnd;
	while (i < j)
	{
		while (i<j)
		{
			// 右侧扫描
			if (array[j] > array[i])
			{
				j--;
			}else
			{
				T temp = array[j];
				array[j] = array[i];
				array[i] = temp;
				i++;
				break;
			}
		}
		while (i<j)
		{
			// 左侧扫描
			if (array[i] < array[j])
			{
				i++;
			}else
			{
				T temp = array[j];
				array[j] = array[i];
				array[i] = temp;
				j--;
				break;
			}
		}

	}
	return i;
}
快速排序递归进行:如果待排序列只有一个元素,结束递归.否则,对序列进行一次划分.再将对划分后的两个子序列进行快速排序.
template <class T>
void quickSort(T array[], int nStart, int nEnd)
{
	if (nStart < nEnd)
	{
		// 一次划分
		int pivot = Partition(array, nStart, nEnd);
		quickSort(array, nStart, pivot-1); // 左侧递归
		quickSort(array, pivot+1, nEnd); // 右侧递归
	}
}
最好情况下,O(n*log2n);
最坏情况下O(n^2)
平均性能O(n*log2n)
由于快速排序是递归的,需要一个栈来存放每一次递归调用的必要信息.所以栈平均深度为O(log2N);
快速排序适用于待排序记录个数很大且原始记录随机排列的情况.快速排序的平均性能是迄今为止所有内排序算法中最好的一种.快速排序应用广泛,典型应用是UNIX系统调用库函数例程中qsort函数.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值