经典内部排序之交换排序

经典内部排序算法有交换排序、插入排序、选择排序、归并排序、分配排序。

分类如下:

交换排序:冒泡排序、快速排序。

插入排序:直接插入排序、折半插入排序、希尔排序。

选择排序:直接选择排序、堆排序。

归并排序

分配排序:基数排序、桶排序。

本博文将介绍交换排序。

一、冒泡排序

冒泡排序算法的运作如下:

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
void Bubble_Sort(int *arr,int len)
{
	int i,j,exchange;
	bool flag = true;   //增设标志位,如果已经排好,则不再进行下次冒泡排序
	for(i=0; i<len-1 && flag; i++)//i标记循环次数,共进行len-1次循环
	{
		flag = false;//每次遍历开始时,初始状态为未交换
		for(j=0;j<len-i-1;j++)//第i+1次遍历
			if(arr[j] > arr[j+1])
			{
				exchange = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = exchange;
				flag = true;
			}
	}
}


算法复杂度为O(N^2)。

二、快速排序

思想

快速排序采用的思想是分治思想。

快速排序是找出一个元素(理论上可以随便找一个)作为基准(pivot),然后对数组进行分区操作,使基准左边元素的值都不大于基准值,基准右边的元素值 都不小于基准值,如此作为基准的元素调整到排序后的正确位置。递归快速排序,将其他n-1个元素也调整到排序后的正确位置。最后每个元素都是在排序后的正 确位置,排序完成。所以快速排序算法的核心算法是分区操作,即如何调整基准的位置以及调整返回基准的最终位置以便分治递归。

举例说明一下吧,这个可能不是太好理解。假设要排序的序列为

2   2 4 9 3 6 7 1 5 首先用2当作基准,使用i j两个指针分别从两边进行扫描,把比2小的元素和比2大的元素分开。首先比较2和5,5比2大,j左移

2   2 4 9 3 6 7 1 5 比较2和1,1小于2,所以把1放在2的位置

2   1 4 9 3 6 7 1 5 比较2和4,4大于2,因此将4移动到后面

2   1 4 9 3 6 7 4 5 比较2和7,2和6,2和3,2和9,全部大于2,满足条件,因此不变

经过第一轮的快速排序,元素变为下面的样子

[1] 2 [9 3 6 7 4 5]

之后,在把2左边的元素进行快排,由于只有一个元素,因此快排结束。右边进行快排,递归进行,最终生成最后的结果。

快速排序函数,通过递归实现
void Quick_Sort(int *a,int low,int high)
{
	int pos;

	if(low < high)
	{
	   pos = findPoss(a,low,high);
	   Quick_Sort(a,low,pos-1);
	   Quick_Sort(a,pos+1,high); 
	}
	return ;
}

/*
该函数返回分割点数值所在的位置,a为待排序数组的首地址,
low刚开始表示排序范围内的第一个元素的位置,逐渐向右移动,
high刚开始表示排序范围内的最后一个位置,逐渐向左移动
*/
int findPoss(int *a,int low,int high)
{
	int val = a[low];
	while(low < high)
	{
	   while(low<high && a[high]>=val)
	      high--;
	   a[low] = a[high];

	   while(low<high && a[low]<=val)
	      low++;
	   a[high] = a[low];	     
	}

	//最终low=high
	a[low] = val;
	return low;
}

算法复杂度:平均O(NlgN),最坏O(N^2)。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值