【内部排序】四:冒泡排序(Bubble Sorting)详解与代码

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

两种交换排序:

      (1)冒泡排序

      (2)快速排序


一、冒泡排序的基本思想:

通过无序区中相邻记录关键字间的比较和位置的交换,使关键字最小的记录如气泡一般逐渐往上“漂浮”直至“水面”。

整个算法是从最下面的记录开始,对每两个相邻的关键字进行比较,且使关键字较小的记录换至关键字较大的记录之上,使得经过一趟冒泡排序后,关键字最小的记录到达最上端,接着再在剩下的记录中找关键字次小的记录,并把它换在第二个位置上。依次类推,一直到所有记录都有序为止

冒泡排序的步骤如下:(从小到大)

    1、依次比较序列中相邻的两个元素,将较小的放在前面,这样一趟比较后,最小的元素就放在了第一个位置;(冒泡)

    2、再依次比较相邻的两个元素,将第二小的元素最终放到第二个位置;

    3、依次循环,直到最大的元素放在了最后一个位置,排序完成。

    根据以上思想,很容易写出代码:

/*
冒泡排序后的顺序为从小到大
*/
void Bubble_Sort(int *a,int n)
{
	int i,j,temp;
	for(i=0;i<n-1;i++)
		for(j=n-1;j>i;j--)
			if(a[j] < a[j-1])
			{
				temp = a[j];
				a[j] = a[j-1];
				a[j-1] = temp;
			}
}

网上还有一种写法,每一趟比较把最大的元素放到最后的位置,就是大的数沉底。个人觉得冒泡冒泡就是往上冒,推荐使用上面的写法!

二、改进冒泡排序 

无论原始序列的排序是怎样的(哪怕已经是从小到大排好的),它都要进行n-1趟比较,每趟比较又要进行n-i-1次相邻元素间的比较(i为从0开始计的第i趟比较)。若在某一趟排序中未发现气泡位置的交换,则说明待排序的无序区中所有气泡均满足小者在上,大者在下的原则,因此,冒泡排序过程可在此趟排序后终止。即很有可能还没有进行第n-1趟比较,已经完成了排序。基于此,我们可以做如下改进:设置一个标志位,在每趟排序开始前,先将其置为FALSE。若排序过程中发生了交换,则将其置为TRUE。各趟排序结束时检查标志位,若未曾发生过交换则终止算法,不再进行下一趟排序。代码实现如下:

void Bubble_Sort(int *a,int n)
{
	int i,j,temp;  
	for(i=0;i<n-1;i++)			//进行n-1趟排序
	{
		bool flag = false;		//增设标志位,判断是否已经完成排序
		for(j=n-1;j>i;j--)		//比较,找出最小关键字的记录
		{
			if(a[j] < a[j-1])
			{
				temp = a[j];
				a[j] = a[j-1];
				a[j-1] = temp;
				flag=true;
			}
		}
		if (!flag)				//本趟没有发生交换,中途结束算法
		{
			return;
		}
	}
}

三、冒泡算法分析 

(1)算法的最好时间复杂度
     若文件的初始状态是正序的,一趟扫描即可完成排序。所需的关键字比较次数C和记录移动次数M均达到最小值:
        Cmin=n-1
        Mmin=0。
     冒泡排序最好的时间复杂度为O(n)。

(2)算法的最坏时间复杂度

     若初始文件是反序的,需要进行n-1趟排序。每趟排序要进行n-i次关键字的比较(1≤i≤n-1),且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下,比较和移动次数均达到最大值:
        Cmax=n(n-1)/2=O(n2)
        Mmax=3n(n-1)/2=O(n2)
    冒泡排序的最坏时间复杂度为O(n2)。

(3)算法的平均时间复杂度为O(n2)
     虽然冒泡排序不一定要进行n-1趟,但由于它的记录移动次数较多,故平均时间性能比直接插入排序要差得多。

(4)算法稳定性

     冒泡排序是就地排序,且它是稳定的。

参考:

http://blog.csdn.net/morewindows/article/details/6657829

http://blog.csdn.net/ns_code/article/details/20065107

你可能感兴趣的:(数据结构,算法,冒泡排序,交换排序)