交换类排序--冒泡、快速

一、冒泡排序

1. 执行过程:

原始序列:49,38,65,97,76,13,27,49

1)1号和2号比较,49>38,交换。

    38,49,65,97,76,13,27,49

2)2号和3号比较,49<65,不交换。

    38,49,65,97,76,13,27,49

3)3号和4号比较,65<97,不交换。

    38,49,65,97,76,13,27,49

4)4号和5号比较,97>76,交换。

    38,49,65,76,97,13,27,49

5)5号和6号比较,97>13,交换。

    38,49,65,76,13,97,27,49

扫描二维码关注公众号,回复: 142812 查看本文章

6)6号和7号比较,97>27,交换。

    38,49,65,76,13,27,97,49

7)7号和8号比较,97>49,交换。

    38,49,65,76,13,27,49,97

至此,一趟冒泡排序结束。

2. 算法思想:

代码:

void BubbleSort(int R[],int n)
{
	int i,j,flag;
	int temp;
	for(i = n-1; i >= 1; --i)
	{
		flag = 0;
		for(j = 1;j <= i;++j)
		{
			if(R[j-1] > R[j])
			{
				temp = R[j];
				R[j] = R[j-1];
				R[j-1] = temp;
				flag = 1  //如果没发生交换,则flag为0;如果发生交换,则flag改为1
			}
			if(flag == 0)
				return;
		}		
	}
}

3. 复杂度分析:

(1)时间复杂度分析
     由冒泡排序算法代码,可以选取最内层循环中的关键字交换操作作为基本操作。
    1)最坏的情况,即整个序列是逆序的,则内层循环中if语句的条件 R[j]<R[j-1]始终成立,基本操作执行的次数为n-i。i的取值为1~n-1。总执行次数为(n-1+1)(n-1)/2=n(n-1)/2,时间复杂度为 O(n²)

    2)最好的情况,即整个序列已经有序,则内层循环中if语句的条件R[j]<R[j-1]始终不成立的。时间复杂度为O(n)

    综合上述两种情况,本算法的平均时间复杂度为O(n²)。

(2)空间复杂度为 O(1)

二、快速排序

1. 执行过程:

原始序列:49,38,65,97,76,13,27,49

                  i                                                   j(i 和 j 开始时分别指向头、尾关键字 )

进行第一趟快排,以49作为枢纽,整个过程是一个交替扫描和交换的过程。

1)使用 j ,从序列最右端开始向前扫描,直到遇到比49小的数27,j 停在这里。

    49,38,65,97,76,13,27,49

      i                                           j

2)将27交换到序列前端 i 的位置。

    27,38,65,97,76,13,    ,49

      i                                          j

3)使用 i ,变换扫描方向,从前向后扫描,直到遇到比49大的数65,i 停在这里。

    27,38,65,97,76,13,    ,49

                    i                            j

4)将65交换到序列后端 j 的位置。

    27,38,    ,97,76,13,65,49

                   i                             j

5)使用 j ,变换扫描方向,从后向前扫描,直到遇到比49小的数13,j 停在这里。

    27,38,    ,97,76,13,65,49

                   i                       j

6)将13交换到序列前端 i 的位置。

    27,38,13,97,76,    ,65,49

                    i                     j

7)使用 i ,变换扫描方向,从前向后扫描,直到遇到比49大的数97,i 停在这里。

    27,38,13,97,76,    ,65,49

                            i             j

8)将97交换到序列前端 j 的位置。

    27,38,13,     ,76,97,65,49

                            i              j

9)使用 j ,变换扫描方向,从后向前扫描,直到遇到比49小的数,当i 和 j 相遇时,扫描结束。

    27,38,13,    ,76,97,65,49

                            ij

10)此时 i 等于j 的这个位置就是49的最终位置。第一趟快速排序结束。

    27,38,13,49,76,97,65,49

                            ij

    接下来,按照同样的方法对序列{27,38,13}和{76,97,65,49}分别进行排序。

2. 算法思想:

代码:

void QuickSort(int R[],int low,int high) //对从R[low]到R[r]的关键字进行排序
{
	int temp;
	int i = low, j = r;
	if(low < high)
	{
		temp = R[low];
		while(i != j)
		{
			while(i<j && R[j]>=temp)
				--j;               //从右往左扫描,找到一个小于temp的关键字
			if(i < j)
			{
				R[i] = R[j];
				++i;
			}
			while(i<j && R[i]<temp)
				++i;               //从左往右扫描,找到一个大于temp的关键字
			if(i < j)
			{
				R[j] = R[i];
				--j;
			}
		}
		R[i] = temp;                        //将temp放在最终位置
		QuickSort(R,low,i-1);               //递归地对temp左边的关键字进行排序
		QuickSort(R,i+1,high);              //递归地对temp右边的关键字进行排序
	}
}

3. 复杂度分析:

(1)时间复杂度:最好的情况O(nlogn),待排序列越接近无序,算法效率越高;

                             最差情况O(n²),待排序列越接近有序,算法效率越低。

(2)空间复杂度为O(logn)

        快速排序是递归进行的,递归需要栈的辅助,因此它需要的辅助空间较大。




猜你喜欢

转载自blog.csdn.net/wh43023/article/details/79451435