改进的冒泡排序算法

这里改进的冒泡算法并不只是用一个标记记录有没有数据进行交换,也不只是用前置标记来记录前面不需要比较的数列的下标,而且从前后两个方向进行标记,避免前面有序和后面有序的比较,从而提高速度。

冒泡算法的改进思想:

1.记录从第0下标开始一直递增的最后一个数的下标start,在以后的每趟排序中都是从start下标开始比较,免去了从头到此下标的比较

2.记录从最后一个下标开始一直递减的最后一个下标end,在以后的每趟排序中只要判断a[end-1]和a[end],如果a[end]大,则后面的就不需要比较和交换

3.数组的长度n在每趟排序后都会n--;

4.同时当end<start时表明数组中没有可以交换的元素了,则排序完成

其实改进的冒泡算法并不能缩短很长的时间,在特大的数组长度时才会有所体现,但是在数组长度太大就不会用冒泡排序了,对于n特别大的时候,用户是容忍不了时间复杂度为o(n^2)的排序算法的

实现代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <time.h>
/*******************************************
*改进的冒泡算法
*******************************************/
void main()
{
	int n;  //数组的长度
    int start = 0;  //前置标记
	
	printf("请输入数组的长度:\n");
	scanf("%d",&n);

	int *a = (int *)malloc(n*sizeof(int));
	//对数组进行初始化操作
	int count=n-1; //记录循环的趟数
	int end = n-1;  //后置标记
	srand(time(0));
	for(int i=0; i<n; i++)
	{
		a[i] = rand()%n;
	}

	//输出排序前的数组序列
	printf("\n");
	printf("排序前的数组序列:\n");
	for(i=0; i<n; i++)
	{
		printf("%d\t",a[i]);
	}

	//先找到前置标记
	i = 0;
	while(a[i]<=a[i+1] )
	{
		i++;
	}
	start = i;

	i=n-1;
	while(a[i-1]<=a[i])
	{
		i--;
	}
	end = i;

	//输出前置标记
	printf("\n");
	printf("前置标记为%d\n",start);
	printf("后置标记为%d\n",end);

	//排序
	while(start < end){
		for(i=start; i<end-1; i++)
		{
			if(a[i] > a[i+1] && i+1<end)
			{
				int temp = a[i];
				a[i] = a[i+1];
				a[i+1] = temp;
			}
		}

	
		for(;i<count; i++)
		{
			if(a[i] > a[i+1])
			{
				int temp = a[i];
				a[i] = a[i+1];
				a[i+1] = temp;
			}
		}
		//对前置标记进行修改
		if(a[start-1] > a[start] && start>0)
		{	
			start--;
			if(start <0)
			{
				start = 0;
			}
		}
    	else
		{
			while(a[start]<=a[start+1] && start<end)	
			{
				start++;
			}
		}
		//对后置标记进行修改
		count--;
		while(a[end-1]<=a[end] && end>=start)
		{
			end--;
			if(end > count)
			{
				end = count;
			}
		}
		//count--;
	}

	//输出排序后的数组序列
	printf("\n");
	printf("排序后的数组序列:\n");
	for(i=0; i<n; i++)
	{
		printf("%d\t",a[i]);
	}

	free(a);
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值