数据结构之排序算法之O(n^2)

在数据结构中讲解了7中排序算法,冒泡、选择、插入、希尔、堆排序、归并、快速排序。希尔排序感觉有点神,还没搞明白,以后再说。

本篇讲述冒泡、选择、插入这3种时间复杂度O(n^2)的算法

冒泡排序

冒泡排序非常简单,但是如果正常写的话还是有优化的余地的,一般我们写的代码为:

void BubbleSort_1(double *a,int low,int high)
{
	if (!a||high<low)
		return;

	int i,j;
	for (i=low;i<=high-1;i++)
	{
		for (j=i+1;j<=high;j++)
		{
			if (a[i]>a[j])
			swap(&a[i],&a[j]);
		}
	}
}



但是这种方法后面部分(i后面的数组)的数值顺序是不变的,如果按照正宗的“冒泡”来的话,每一次 i 循环后,较小的数都会相应的向前靠拢,代码修改为:

void BubbleSort_2(double *a,int low,int high)
{
	if (!a||high<low)
		return;

	int i,j;
	for (i=low;i<=high-1;i++)
	{
		for (j=high-1;j>=i;j--)
		{
			if (a[j]>a[j+1])
				swap(&a[j],&a[j+1]);
		}
	}
}



还有一种,如果某次循环后数组后面已经是顺序的话,那就不需要在进行排序了,加入一个标志位即可:

void BubbleSort_3(double *a,int low,int high)
{
	if (!a||high<low)
		return;

	int i,j;
	bool sign=true;
	for (i=low ; i<=high-1&&sign ; i++)
	{
		sign=false;
		for (j=j=high-1 ; j>=i ; j--)
		{
			if (a[j]>a[j+1])
			{
				swap(&a[j],&a[j+1]);
				sign=true;
			}
		}
	}
}


选择排序

这个就比较简单了,从首位开始,每次都选择当前位和后面数组中最小的来交换当前位。

void SelectSort(double* a,int low,int high)
{
	if (!a||high<low)
		return;

	int i,j,min;
	for (i=low;i<=high;i++)
	{
		min=i;
		for (j=i+1;j<=high;j++)
		{
			if (a[j]<a[min])
				min=j;
		}
		swap(&a[i],&a[min]);
	}
}

插入排序

插入排序的算法也很简单,就是假设当前位之前的数组已经排序好,然后把当前位插入到前面数组的合适位置,具体做法为依次比较,直到找到比当前位小的值。

void InsertSort(double* a,int low,int high)
{
	if (!a||high<low)
		return;

	int i,j;
	double key;

	for (i=low ; i<high ; i++)
	{
		j=i;
		key=a[i+1];
		while (a[j]>key&&j>=low)
		{
			a[j+1]=a[j];
			j--;
		}
		a[j+1]=key;
	}
}


可以粗略估计下这3个排序的优劣,冒泡和选择排序的比较次数都是相同的,都是O(n^2),但是选择排序的交换操作比冒泡少,所以选择要比冒泡强。而插入排序在最坏情况下的比较次数和选择排序是一样的,但是如果数组已经基本有序的话,那么内循环的执行次数是比较少的,

所以平均情况下,插入排序 优于 选择排序 优于 冒泡排序

现在我们来测试下这3种方法的时间,测试数组大小为5万,里面的值是随机生成的浮点值。(结果冒泡中第一种时间最短,好纠结啊)



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值