【算法】改进的冒泡排序 O(n^2) 稳定的 C语言

改进的冒泡排序

 一、算法描述                                                     

基于原冒泡排序

 

每次选取第一个元素作为主元往后进行比较,若遇到比它小的则放到它左边(即进行交换),若遇到比它大的则选取大的作为主元进行后续比较,每趟选取了无序列中最大元素放置无序列最后位,当一趟比较没有发生交换则为有序序列,即像吐泡泡一样第一次把最大的数吐到最末位,第二趟把倒数第二大的数吐到倒数第二位。。。。。

 

可记录每趟最后一次发生交换的两记录的位置,假设记其下标为last,也即在该位置之后(到序列末尾)都是有序数列,则规定下趟排序的范围则为0last,同样当某趟排序不发生交换时完成排序

 二、算法分析                                                     

原每趟排序的范围固定为0n0n-10n-2......改进后则每次都为0last,且每次的last是远可能小于且一定会小于n-i的,当last0是则完成排序,这样则大大加快算法的执行时间

 

 三、算法实现代码                                                 

void Gaijindemaopaopaixu(List*lst)
{
	int i, j;
	int temp;//用于交换
	int last ;//用于记录最后发生交换的位置
	i = lst->Size - 1;
	while (i > 0) //当i=0时结束
	{   
		last = 0;//也即若不发生交换,i赋值0,结束排序
		for (j = 0; j < i; j++)//完成0到i期间的比较,i逐渐变小
		{                                               
			if (lst->Elements[j + 1] < lst->Elements[j])//若主元大于需比较的也即其后面的元素,进行交换,也即
			{                             //放到他左边若小于或等于,不做任何处理,也即换取了后一个数作为主元
				temp = lst->Elements[j + 1];
				lst->Elements[j + 1] = lst->Elements[j];
				lst->Elements[j] = temp;

				last=j;//记录最后发生交换的位置
			}
		}			
		i=last;//缩短范围
	}
}



 四、实例测试代码                                                 

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MaxSize 99


typedef struct list {
	int Size;//大小 
	int Elements[MaxSize];//用数组存放 
}List;//定义顺序表

void Gaijindemaopaopaixu(List*lst);//改进冒泡排序函数声明

int main(void) {
	List a;//定义一个顺序表对象a
	int i;
	srand((unsigned)time(NULL)); //随机数种子
	a.Size = 10;//定义大小为10

	for (i = 0; i<10; i++)
	{
		a.Elements[i] = rand() % 10;//初始化顺序表
	}

	printf("    初始原表为:");
	for (i = 0; i < 10; i++)
	{
		printf("%d  ", a.Elements[i]);
	}
	printf("\n");

	Gaijindemaopaopaixu(&a);//调用改进冒泡函数,修改值需传入地址

	printf("经改进冒泡排序:");
	for (i = 0; i < 10; i++)
	{
		printf("%d  ", a.Elements[i]);
	}

	getchar();
	return 0;
}
void Gaijindemaopaopaixu(List*lst)
{
	int i, j;
	int temp;//用于交换
	int last ;//用于记录最后发生交换的位置
	i = lst->Size - 1;
	while (i > 0) //当i=0时结束
	{   
		last = 0;
		for (j = 0; j < i; j++)//完成0到i期间的比较,i逐渐变小
		{                                               
			if (lst->Elements[j + 1] < lst->Elements[j])//若主元大于需比较的也即其后面的元素,进行交换,也即
			{                             //放到他左边若小于或等于,不做任何处理,也即换取了后一个数作为主元
				temp = lst->Elements[j + 1];
				lst->Elements[j + 1] = lst->Elements[j];
				lst->Elements[j] = temp;

				last=j;//记录最后发生交换的位置
			}
		}			
		i=last;//缩短范围
	}
}



 

posted @ 2015-11-27 14:39  Ahair  阅读(2006)  评论(0编辑  收藏  举报