学习一下选择排序,快速排序

1.选择排序

我们可以根据这动图看到,就是在这个数组里面我们选出最小的放进第一个位置,然后再选除了第一个位置最小的,剩下的数里面最小的放到第二个位置,是不是非常简单呢。

void SelectSort2(int* arr, int n)
{
	int begin = 0;
	
	while (begin < n)
	{int mini = begin;
		for (int i = begin+1; i < n; i++)
		{
			if (arr[i] < arr[mini])
			{
				mini = i;
			}
		}
		Swap(&arr[begin], &arr[mini]);
		begin++;
	}
}

然后呢,我们可以升级一下,那就是选两个值,一个最小的,放在最左边,一个最大的,放在最右边,道理几乎差不多。

值得一提的就是如果出现了图中这样的情况,该怎么呢,先mini和begin的值被换走了,max下标不是最大的值了,而mini通过交换,mini代表了最大值的下标,所以这时候要判断一下,begin和max相等不,否则,首先交换begin和mini会影响到max

void SelectSort1(int* arr, int n)
{
	int end=n-1;

	int begin=0;
	
	while (end > begin)
	{ 
		int mini = begin, max = begin;
		for (int i = begin+1; i <= end; i++)//找最大的和最小的下标
			
		{
			if (arr[i] < arr[mini])
			{
				mini = i;
			}
			if (arr[i] > arr[max])
			{
				max = i;
			}
		}
		Swap(&arr[begin], &arr[mini]);
		if (max == begin)//当begin==max 的时候,max指向的数会被
			//上次的Swap交换给换走了,begin是最小的值了,max指向的数在mini那
		{
			max = mini;
		}
		Swap(&arr[end], &arr[max]);
		begin++;
		end--;
	}

}

2.快速排序

通过动图我们可以直到快速排序的原理是,以左下角的数为key,然后右边的指针先走,right去找比key小的数,left再走,去找比key大的数,然后两个数进行交换,然后right再往左走,left再走,直到左右相遇,也就是left==right了,最后一步把key和left和right相遇的位置进行交换。并且,他们相遇的地方一定比key小。并且key就到了它在数组中正确的位置,因为左边的数都比它小,右边的数都比它大。接着开始递归就好了。

为什么,相遇的地方一定比key小呢?

left和right要想遇到,那就只有两种可能,要么是left停下,right向左走,要么就是right停下,left向右走,然后碰到。那么right找的是什么,找的是比key小的数字,它停下的地方就是比key小的地方,所以left向右走,碰到的时候,key绝对要比相遇的大。然后就是left停下的地方,我们首先想想,left是怎么停下的,它遇到了比key大的数,停下了,然后和right互换了一下,所以left停下的时候代表的也是比key小的数,等到right向左边走,就会遇到,所以key一定比相遇到的值大。

void QuickSort(int* arr, int left, int right)
{
	if (left >= right)//单个数字,或者不存在的数组
	{
		return;
	}
	int begin = left;
	int end = right;
	int keyi = left;
	while (left < right)
	{
		while (left<right && arr[right]>=arr[keyi])//keyi在左边就右边先走
		{
			right--;
		}
		while (left < right && arr[left] <= arr[keyi])
		{
			left++;
		}
		Swap(&arr[left], &arr[right]);
	}
	Swap(&arr[left], &arr[keyi]);
	keyi = left;
	QuickSort(arr, begin, keyi - 1);
	QuickSort(arr, keyi + 1, end);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值