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);
}