【交换排序】冒泡排序

冒泡排序(Bubble Sort)
     冒泡排序是基于交换排序的一种排序,交换排序的基本思想,是两两比较待排序记录的关键字,一旦发现两个记录不满足次序要求时则进行交换,直到整个序列全部满足要求为止。 冒泡排序是一种最简单的交换排序方法,它通过两两比较相邻记录的关键字,如果发生逆序,则进行交换,从而使关键字小的记录如气泡一般逐渐往上“漂浮”(左移),或者使关键字大的 记录如石块一样逐渐向下“坠落”(右移)。

[算法思想]

1)设待排序的记录存放在数组r[1..n]中。首先将第一个记录的关键字和第一个记录的关键字进行比较,若为逆序,即r[1]>r[2],则交换两个记录。然后比较第二个记录和第三个记录的关键字。依次类推,直到第n-1个记录和第n个记录的关键字进行过比较为止。上述过程称为第一趟起泡排序,其结果使得关键字最大的记录被安置到最后一个记录的位置上。

2)然后进行第二趟起泡排序,对前n-1个记录进行同样操作,其结果是使得关键字次大的记录被安置到第n-1个记录的位置上。

3)重复上述比较和交换过程,第i趟是从r[1]到r[n-i+1]依次比较相邻两个记录的关键字,并在“逆序”时交换相邻记录,其结果是这n-i+1个记录中关键字最大的记录被交换到第n-i+1的位置上。直到某一趟排序过程中没有进行交换记录的操作,说明序列已全部达到排序要求,则完成排序。

  例 已知待排序记录的关键字序列为{70,30,40,10,80,20,90,100,75,60,45},请给出用冒泡排序法进行排序的过程。

   待排序的记录共有11个,但算法在第七趟排序过程中没有进行交换记录的操作,则完成排序。
[算法描述]
void BubbleSort(int r[],int Length)
{
	/* 对顺序表r做冒泡排序 */
	int m = Length-1;int flag = 1;/* flag用来标志某一趟排序是否发生交换 */
	while((m > 0)&&(flag == 1))
	{
		flag=0;                   /*flag置为0,如果本趟排序没有发生交换,则不会执行下一趟排序*/
		for(int j = 1;j< m;j++)
		{
			if(r[j]>r[j+1])
			{
				flag=1;          /* flag置为1,表示本趟排序发生了交换 */
				/* 交换前后两个记录 */
				int t=r[j];       
				r[j]=r[j+1];
				r[j+1]=t;
			}
		}
		--m;
	}
}
[算法分析]
1.时间复杂度
   最好情况(初始序列为正序):只需进行一趟排序,在排序过程中进行n-1次关键字减的比较,且不移动记录;
   最坏情况(初始序列为逆序):需进行n-1趟排序,总的关键字比较次数KCN和记录移动次数RMN(每次交换都要移动3次记录)分别为   KCN=n(n-1)/2=(n^2)/2     RMN=3n(n-1)/2=3(n^2)/2
    所以在平均情况下,冒泡排序关键字的比较次数和记录移动次数分别约为(n^2)/4和3(n^2)/4,时间复杂度为O(n^2)。
2.空间复杂度
    冒泡排序只有在两个记录交换位置时需要一个辅助空间用做暂存记录,所以空间复杂度为O(1)。
[算法特点]

1)是稳点排序。

2)可用于链式存储结构。

3)移动记录次数较多,算法平均时间性能比直接插入排序差。当初始记录无序,n较大时,此算法不宜采用。
[完整代码]
#include<iostream>
using namespace std;
void BubbleSort(int r[],int Length)
{
	/* 对顺序表r做冒泡排序 */
	int m = Length-1;int flag = 1;/* flag用来标志某一趟排序是否发生交换 */
	while((m > 0)&&(flag == 1))
	{
		flag=0;                   /*flag置为0,如果本趟排序没有发生交换,则不会执行下一趟排序*/
		for(int j = 1;j< m;j++)
		{
			if(r[j]>r[j+1])
			{
				flag=1;          /* flag置为1,表示本趟排序发生了交换 */
				/* 交换前后两个记录 */
				int t=r[j];       
				r[j]=r[j+1];
				r[j+1]=t;
			}
		}
		--m;
	}
}
int main()
{
	int  a[12]={0,70,30,40,10,80,20,90,100,75,60,45};  /* 从a[1]开始 */
	BubbleSort(a,12);
	for(int i=1;i<12;i++)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;
	return 0;
}
[运行结果]


附:<啊哈!算法>冒泡排序的实现
#include<stdio.h>
int main()
{
	int a[101],n,i,j,t;


	scanf_s("%d",&n);
	for(i=1;i<=n;i++)
	{
		scanf_s("%d",&a[i]);
	}
	//开始冒泡排序
	for(i=1;i<=n-1;i++)
	{
		for(j=1;j<n-i;j++)
		{
			if(a[j]>a[j+1])
			{
				t=a[j];
				a[j]=a[j+1];
				a[j+1]=t;
			}
		}
	}
	printf("%d ",a[1]);
	for(i=2;i<=n;i++)
	{
		if(a[i]!=a[i-1])  //去重
		{
			printf("%d ",a[i]);
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值