排序算法之快速排序

冒泡排序的思路:

就是选取一个数为基准,将小于基准的放在左边,大于基准的放在其右边。然后左右两边各自找一个基准,依次用此方法。

举个栗子:

按高矮顺序排序,经常我们说向基准看齐。比如男性基准身高为170,小于170的放在左边,大于170放在右边,比如 168,158,170,175,190,185。

然后左边:168,158。再找个基本依次用这个方法排序。

同理右边:175,190,185。也再找个基准去按照这个方法去排序。

代码:

int partition(int _arry[], int _nLeft, int _nRight)  //找基准数 划分
{
	if (_nLeft>_nRight)
	{
		return -1;
	}
	int i = _nLeft + 1;//第二个数为左"指针"
	int j = _nRight;//最后一个数为右"指针"
	int temp = _arry[_nLeft];//以最左边这个数为基准
	while (i <= j)
	{
		while (_arry[i] < temp)//左与基准值比较,小于基准就移动,当大于了基准就退出循环,轮到右值移动
		{
			i++;
		}
		while (_arry[j] > temp)//继续直到右值小于等于temp就停下来。
		{
			j--;
		}
		if (i < j)//这个时候如果i<j的话,就交换左右两值
		{
			swap(_arry[i++], _arry[j--]);//交换之后呢,继续往下走
		}
		else {
			i++;
		}
	}
    //就是可以看成两个挡板,一个档板比基准值大,一个挡板比其小,然后将基准值夹在中间
	swap(_arry[j], _arry[_nLeft]);
	return j;//得到分割线的索引,将其分割成两个部分
}
void testKuaiSu(int _arry[], int _nLeft,int _nRight)
{
	if (left > right)
		return;
	int j = partition(_arry, _nLeft, _nRight);
	if (j>=0)
	{
		testKuaiSu(_arry, _nLeft, j - 1);//左边继续分割排序
		testKuaiSu(_arry, j + 1, _nRight);//右边也是继续排序
	}
}
int main()
{
	testKuaiSu(testarray,0,9);
}

优化的思路:

1、基准值的选取,虽然基准值无论怎么选都不会影响其结果,但是可以影响排序的整体时间。最好的情况是每次分割的时候能够左右两边数据是均衡的,这样排序的次数会减少。

2、如何比较快的方法将基准移动中间位置。

目前想到的就是这两个优化思路。

对于第一个优化思路----基准值的选取:

1、假如选取第一个或者最后一个值作为基准值,上面的代码就是以第一个值作为基准值,有可能导致数据一边倒的情况造成数据分布不均匀。

     那我们能不能一个比较好的基准值,使其数据分布更加均匀,这个好像机器学习的聚类算法的思路,更可能让数据更加均匀分布。

      那么首先想到的就是中位数,居中嘛。咱们每次都找到中位数作为基准值,但是我们计算中位数貌似耗费时间。那么我们随机采取找三个元素,取其中值这样是不是会好一点。具体方法都是看我们自己去选取,这个没有统一的,有时也与我们的数据分布情况有关系。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值