冒泡排序及优化

冒泡排序通常是最早接触的一种排序
原理是:(假设是按照从小到大的顺序排列)每一次遍历都会把当前的最大值归置到应有的位置,在下一次遍历时忽略最后的已经归置好的,在前面未排序的部分再次重复,每一次遍历都不能少。

void bubbleA(int num[], int size)//size是数组规模
{
	int i, j;
	for (j = 0; j < size; j++)
		for (i = 0; i < size - j - 1; i++)//每一次遍历要忽略掉最后的
			if (num[i] > num[i + 1])
				swap(num[i], num[i + 1]);
}

在此基础上加一个判断s,如果已经排好序(也就是没有逆序出现),那么就直接跳出循环了,所以假如这个函数从一开始就是排好序的,那么上来第一次遍历就可以跳出循环,但是bubbleA是一次遍历都不能少的

void bubbleB(int num[], int size)
{
	int i,j;
	bool s = false;//s是未排好序的
	while(!s)
	{
		s = true;//先假设s已经排好了
		for (i = 0; i < size-1; i++)
			if (num[i] > num[i + 1])
			{
				s = false;//如果遇到逆序需要交换的,也就是说这个函数还没有排好序
				swap(num[i], num[i + 1]);
			}
	}
}

如果代码的后一段是已经排好序的,那么下列代码可以检测到最后一组逆序对出现的位置,并直接忽略掉最后面已经排好序的,缩小数组规模,继续检测,所以这个是断断续续的,可能排着排着就出来一些顺序的,就忽略,继续排着排着又出来一些顺序的…
所以如果数组比较有规律一点,这个算法效率会高一点。

void bubbleC(int num[], int size)
{
	int i, last=0;//last是记录最后的逆序对的位置
	for (int m; size > 1; size = last)//如果最后一堆逆序对在0or1处代表已经排序完全,就可以跳出循环了
	{	
		for (i = last =0; i < size-1; i++)//每进入一次内循环都要将last归零
		{
			if (num[i] > num[i + 1])
			{
				last = i;//记录逆序对位置
				swap(num[i], num[i + 1]);
			}
		}
	}
}

以上三种冒泡排序的写法的在最坏情况下的效率相同。并且优化后的在最好情况下时间复杂度也就线性的
下面是测试代码:

#include<iostream>
using namespace std;
void bubbleA(int num[], int size);
void bubbleB(int num[], int size);
void bubbleC(int num[], int size);
void swap(int* q, int* p)
{
	int t;
	t = *p;
	*p = *q;
	*q = t;
}
int main()
{
	int num[] = { 1,4,2,6,5,7,8,45,33 };
	int size = sizeof(num) / sizeof(int);
	bubbleA(num, size);
	//bubbleB(num, size);
	//bubbleC(num, size);
	for (int i = 0; i < size; i++)
		cout << num[i]<<"  ";
	return 0;
}
void bubbleA(int num[], int size)
{
	int i, j;
	for (j = 0; j < size; j++)
		for (i = 0; i < size - j - 1; i++)
			if (num[i] > num[i + 1])
				swap(num[i], num[i + 1]);
}
void bubbleB(int num[], int size)
{
	int i,j;
	bool s = false;
	while(!s)
	{
		s = true;
		for (i = 0; i < size-1; i++)
		{
			if (num[i] > num[i + 1])
			{
				s = false;
				swap(num[i], num[i + 1]);
			}
		}
	}
}
void bubbleC(int num[], int size)
{
	int i, last=0;
	for (int m; size > 1; size = last)
	{	
		for (i = last =0; i < size-1; i++)
		{
			if (num[i] > num[i + 1])
			{
				last = i;
				swap(num[i], num[i + 1]);
			}
		}
	}
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值