⼏种常⽤的排序算法(c语⾔实现)
概述
最近重新回顾了⼀下数据结构和算法的⼀些基本知识,对⼏种排序算法有了更多的理解,也趁此机会通过博客做⼀个总结。
1.选择排序-简单选择排序
选择排序是最简单的⼀种基于O(n2)时间复杂度的排序算法,基本思想是从i=0位置开始到i=n-1每次通过内循环出i位置到n-1位置的最⼩(⼤)值。
算法实现:
void selectSort(int arr[], int n)
{
int i, j , minValue, tmp;
for(i = 0; i < n-1; i++)
{
minValue = i;
for(j = i + 1; j < n; j++)
{
if(arr[minValue] > arr[j])
{
minValue = j;
}
}
if(minValue != i)
{
tmp = arr[i];
arr[i] = arr[minValue];
arr[minValue] = tmp;
}
}
}
void printArray(int arr[], int n)
{
int i;
for(i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
void main()
{
int arr[10] = {2,5,6,4,3,7,9,8,1,0};
printArray(arr, 10);
selectSort(arr, 10);
printArray(arr, 10);
return;
}
如实现所⽰,简单的选择排序复杂度固定为O(n2),每次内循环出没有排序数列中的最⼩值,然后跟当前数据进⾏交换。由于选择排序通过查最值的⽅式排序,循环次数⼏乎是固定的,⼀种优化⽅式是每次循环同时查最⼤值和最⼩值可以是循环次数减少为(n/2),只是在循环中添加了记录最⼤值的操作,原理⼀样,本⽂不再对该⽅法进⾏实现。
2.冒泡排序
冒泡排序在⼀组需要排序的数组中,对两两数据顺序与要求顺序相反时,交换数据,使⼤的数据往后移,每趟排序将最⼤的数放在最后的位置上,如下:
算法实现:
void bubbleSort(int arr[], int n)
{
int i, j, tmp;
for(i = 0; i < n - 1; i++)
{
for(j = 1; j < n; j++)
{
if(arr[j] < arr[j - 1])
{
tmp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = tmp;
}
}
}
}
void printArray(int arr[], int n)
{
int i;
for(i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
void main()
{
int arr[10] = {2,5,6,4,3,7,9,8,1,0};
printArray(arr, 10);
bubbleSort(arr, 10);
printArray(arr, 10);fortify工具是干嘛的
return;
十六进制转换文字}
如上是⼀种最简单的实现⽅式,需要注意的可能是i, j的边界问题,这种⽅式固定循环次数,肯定可以解决各种情况,不过算法的⽬的是为了提升效率,根据冒泡排序的过程图可以看出这个算法⾄少可以从两点进⾏优化:
1)对于外层循环,如果当前序列已经有序,即不再进⾏交换,应该不再进⾏接下来的循环直接跳出。
2)对于内层循环后⾯最⼤值已经有序的情况下应该不再进⾏循环。
优化代码实现:
如上,当nflag为0时,说明本次循环没有发⽣交换,序列已经有序不⽤再循环,如果nflag>0则记录了最后⼀次发⽣交换的位置,该位置以后的序列都是有序的,循环不再往后进⾏。
3.插⼊排序-简单插⼊排序
插⼊排序是将⼀个记录插⼊到已经有序的序列中,得到⼀个新的元素加⼀的有序序列,实现上即将第⼀个元素看成⼀个有序的序列,从第⼆
个元素开始逐个插⼊得到⼀个完整的有序序列,插⼊过程如下:
如图,插⼊排序第i个元素与相邻前⼀个元素⽐较,如果与排序顺序相反则与前⼀个元素交换位置,循环直到合适的位置。 算法实现:
void bubbleSort_1(int arr[], int n)
{
int i, nflag, tmp;
do
{
nflag = 0;
for (i = 0; i < n - 1; i++)
{
if (arr[i] > arr[i + 1])
补码如何求原码{
tmp = arr[i];
冒泡排序代码c语言arr[i] = arr[i + 1];
arr[i + 1] = tmp;
nflag = i + 1;
}
}
n = nflag;
}while (nflag);
}
void insertSort(int arr[], int n)
{
int i, j, tmp;
for(i = 1; i < n; i++)
{
for(j = i; j > 0; j--)
{摩洛哥西班牙
if(arr[j] < arr[j-1])
{
tmp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = tmp;
}
else
{
break;
}
}
}
return;
}
void printArray(int arr[], int n)
{
int i;
for(i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return;
}
void main()
{
int arr[10] = {2,5,6,4,3,7,9,8,1,0};渐变图形
printArray(arr, 10);
insertSort(arr, 10);
printArray(arr, 10);
return;
}
如上,前⾯提到选择排序不管什么情况下都是固定为O(n2)的算法,插⼊算法虽然也是O(n2)的算法,不过可以看出,在已经有序的情况下,插⼊可以直接跳出循环,在极端情况下(完全有序)插⼊排序可以是O(n)的算法。不过在实际完全乱序的测试⽤例中,与本⽂中的选择排序相⽐,相同序列的情况下发现插⼊排序运⾏的时间⽐选择排序长,这是因为选择排序每次外循环只与选择的最值进⾏交换,⽽插⼊排序则需要不停与相邻元素交换知道合适的位置,交换的三次赋值操作同样影响运⾏时间,因此下⾯对这⼀点进⾏优化:
优化后实现:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论