排序之交换排序:冒泡排序and快速排序

交换排序基本思想:两两比较待排序记录的关键字,发现两个记录次序相反时即进行交换,直至没有反序记录为止。

分类:冒泡排序和快速排序。

1、冒泡排序:

冒泡排序大家都比较熟悉,所以这里不具体说明,请看代码:

void bubble_sort1(int a[],int len)//冒泡排序
{

	for(int i=0;i<len-1;i++)
	{
		for(int j=len-1;j>i;j--)//从后往前交换,最小值冒泡到开头位置
		{
			if(a[i]>a[j])
			{
			   int temp=a[i];
			   a[i]=a[j];
			   a[j]=temp;

			}
		}
	}
}

但是上述程序有一个问题必须要注意下:

就是假如进行到第i次扫描前,数组已经排好序了 ,它还会进行下一次的扫描,很显然最后一次没有必要。

改进后代码如下:

void bubble_sort2(int a[],int len)//冒泡排序
{
	int flag;//用来标志最后一次之前排序 是否已经完成交换,如果完成就没必要进行下一次交换。
	for(int i=0;i<len-1;i++)
	{
		flag=0;
		for(int j=len-1;j>i;j--)//从后往前交换,最小值冒泡到开头位置
		{
			if(a[i]>a[j])
			{
			   int temp=a[i];
			   a[i]=a[j];
			   a[j]=temp;
			   flag=1;
			}
		}
		if(flag!=1)//此趟扫描中没有发生交换 
			return ;
	}
}

上述用一个局部变量flag来记录在本次扫描时有没有进行数据交换,每次扫买哦之前,把flag置0,如果扫描时发生交换,则将flag置1,如果没有则说明数组已经排好序了,不需要进行下一次的扫描。


2、快速排序

快速排序采用分治法。

分治法:将原问题分解为若干个规模更小但结构与原问题相似的子问题,递归的解答这些子问题,然后将这些子问题组合为原问题的解 

快速排序的基本思想:假设当前待排序的无序区为A[low...high] ,利用分治法描述如下:

  (1)分解:在A[low...high]中任选一个记录作为基准(Pivot),以此为基准将当前无序区划分为左右两个较小的区间,并使左边的子区间中所有的记录关键字均小于等于基准记录,右边子区间中的所有记录的关键字均大于等于A[Pivot],而基准记录则位于正确的位置上,不需要参加后续排序。
  (2)求解:通过递归调用快速排序对左右子区间A[low...Pivot-1]和A[Pivot...high]快速排序;
  (3)组合:当求解步骤中的两个递归调用结束时,其左右两个子区间的已有序。因此此步骤可看成空操作。

具体代码如下:

void quick_sort(int a[],int low,int high )
{
	
	int pivot;
	if(low<high)
	{
		pivot=a[low];
		int i=low;
		int j=high;
		while(i<j)
		{
			while(i<j && a[j]>=pivot)
				j--;
			if (i<j)
				a[i++]=a[j];//将比pivot小的元素移到低端

			while(i<j && a[i]<=pivot)
				i++;

			if(i<j)
				a[j--]=a[i];//将比pivot大的元素移到高端
		}
		a[i]=pivot;

		quick_sort(a,low,i-1);
		quick_sort(a,i+1,high);
	}
}
测试程序:

void print(int a[],int len)
{
	for(int i=0;i<len;i++)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;
}

int main()
{
	int a[]={7,3,5,8,9,1,2,4,6};
//  bubble_sort1(a,9);
//	bubble_sort2(a,9);

	quick_sort(a,0,8);
	print(a,9);
	return 0;
}

执行结果:

1 2 3 4 5 6 7 8 9 



猜你喜欢

转载自blog.csdn.net/qq_35965090/article/details/77816292