选择排序算法与⽰例详解(c语⾔)
选择排序是排序算法的⼀种,思想就是,每⼀轮寻数组中最⼤的值或者最⼩的值,放在头部或者放⼊⼀个新的数组。这样经历⼀轮遍历,数组或者新数组就是排好序的,他的⽬的很明确,每次最⼤值或者最⼩值。
这个放在头部,其实头部不是固定不变的,每次都会往后移动⼀位,因为前⾯的数据都是排好序的。这种借助当前数组做排序的算法,是为了节省空间,也是⼀种提⾼效率的办法。
以最⼤值为例,如何最⼤值?⽐较嘛,默认选择第⼀个元素作为最⼤值,依次与数组中的元素⽐较,有⽐它⼤的,就交换,遍历完成,就到了最⼤值。
#include <stdio.h>
int main()
{
int arr[] = {6,5,4,3,2,1,7,8,9,0};
int max = arr[0];
for(int i=1;i<10;i++)
{
if(max<arr[i])
max = arr[i];
}
printf("max=%d\n",max);
return 0;
}
这个最⼤值,就是每次⽐较之后,如果满⾜条件都需要进⾏数组元素交换。也有⼀种做法,记录下标,如果换为交换下标,这样,最后遍历完成,我们取出下标对应的元素即可。
我们来看看选择排序:
#include <stdio.h>
void selectSort(int arr[],int n)
{
int i,j,maxIndex,tmp;
for(i=0;i<n-1;i++)
{
maxIndex = i;
for(j=i+1;j<n;j++)
{
if(arr[maxIndex]<arr[j])
maxIndex = j;
}
tmp = arr[i];
arr[i] = arr[maxIndex];
arr[maxIndex] = tmp;
}
}
int main()
{
int arr[] = {6,5,4,3,2,1,7,8,9,0};
selectSort(arr,10);
for(int i=0;i<10;i++)
printf("%d ",arr[i]);
marginright是什么意思
printf("\n");
return 0;
}
这种排序,我们需要额外申请⼀个变量来记录maxIndex或者minIndex,如果不⽤这个变量,我们就回到了前⾯提到的,每次交换数组元素。
void selectSort(int arr[], int n)
{
int i, j, tmp;
for (i = 0; i < n - 1; i++)
{
for (int j = i + 1; j < n; j++)
{
if (arr[i] < arr[j])
{
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}
}
这种排序,看起来,很像冒泡排序,不同的是,冒泡排序,每次⽐较的是相邻元素,选择排序⽐较的是固定位置的元素和集合中剩余的元素。
我们通过⽰例,来直观感受⼀下两者的区别:
冒泡排序:
选择排序:
冒泡排序算法:
void bubbleSort(int arr[], int n)
{
int i, j, tmp;
for (i = 0; i < n; i++) {
for (j = 0; j < n - 1 - i; j++) {
if (arr[j] < arr[j + 1])
{
tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
代码直观⽐较:
从算法的结果和特点来看,选择排序,前⾯的元素是排好序的,⽽冒泡排序,末尾的元素的排好序的。所以在冒泡排序第⼆层循环⾥⾯,不⽤每次都遍历整个数组,⽽是到n-1-i的位置。他们共同特点是算法复杂度是相同的,都是O(n*n)。冒泡排序代码c语言
这⾥交换元素,我们也⽤了⼀个别的变量,其实也有取巧的算法,连别的变量也不需要的,直接交换两个元素的值:
if (arr[i] < arr[j])
{
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}
这种办法是⼀种很巧妙的算法,是有计算依据的,⼤家可以看看如下的计算过程:
有⼈可能马上觉着,这也太low了,这不就是:
//a=2,b=3
a = a + b;// a = 5
b = a - b;// b = 2
a = a - b; // a = 3
乍⼀看,没⽑病,这没什么好说的,但是你可能忽略的⼀个问题,就是计算机的整数是有范围的,在边界以内,这么来搞没问题,如果两个数字,都在边界Integer.max附近,相加就超出范围了,并不能达到预期的结果,所以说“异或”才是最安全的做法。
其实,这个算法的巧妙之处在于他没有借助第三个变量就交换了两个变量的值,这个算法经常在⾯试题中会出现,当你知道了,就会觉着很简单。
上⾯介绍了选择排序的完整实现,以及各种取巧的办法。貌似很完美了,但是有个问题,就是这种排序,理论上只⽀持⼀种排序,要么升序,要么降序。如果要改变排序规则,我们需要修改交换的判断条件,需要硬编码。在c语⾔中,我们可以借助⼀个回调函数来作为判断的依据,我们在给排序算法传递参数的时候,将回调函数传进去,然后我们只需要修改回调函数的规则即可。
#include <stdio.h>
int compare(int a, int b)
{
java移位计算return a < b?1:0;
}
void selectSort(int arr[], int n, int (*pf)(int, int))
{
for (int i = 0; i < n - 1; i++)
{
for (int j = i + 1; j < n; j++)
{
if (pf(arr[i], arr[j]))
{
arr[i] = arr[i] ^ arr[j];
xml是什么类型
arr[j] = arr[i] ^ arr[j];python代码画螺旋丸
arr[i] = arr[i] ^ arr[j];
}
}
}
}
int main()
{
int arr[] = { 6,5,4,3,2,1,7,8,9,0 };php正则匹配函数
selectSort(arr, 10, compare);
for (int i = 0; i < 10; i++)
printf("%d ", arr[i]);
printf("\n");
return 0;
}
其实这个算法就很接近c语⾔库提供的qsort算法了,看看算法的表⽰:
void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))
其中参数base是数组,nitems表⽰数组元素个数,size表⽰元素的长度,也就是该类型的长度,整型是4,⽐较函数两个参数都是const void *,表⽰任意类型,并不局限于int。
利⽤qsort排序⽰例:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。