十大排序算法可以说是每个程序员都必须得掌握的,对于毕业生,掌握十种排序也能在面试中加分不少。因此我花了一天的时间将十种排序进行整理,并且附上代码以供大家学习。
1. 冒泡排序
冒泡排序算法的思路如下:
- 比较相邻的元素,如果前一个比后一个大,就交换他们两个。
- 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
当一轮循环中未有数据进行交换,则代表数据已经有序,因此没有必要再进行之后的循环。
代码实现:
void swap(int *pa,int *pb){
//交换两个值
int t = *pa;
*pa = *pb;
*pb = t;
}
//冒泡排序
void bubble_sort(int arr[],size_t n){
int i,j;
for(i=0;i<n-1;i++){
int flag = 0; //flag记录一次循环中是否有数据进行交换
for(j=1;j<n-i;j++){
if(arr[j]<arr[j-1]){
//将较大的数值往后移,默认升序
swap(&arr[j],&arr[j-1]);
flag = 1;
}
}
if(flag == 0){
//没有数据进行交换说明该数组已经由于,则可以提前退出
break;
}
}
}
2. 选择排序
选择排序算法的思路如下:
- 遍历数组中的元素可以找到最大值(下标),把最大值和最后一个元素进行交换。
- 排除最后面最大值的数据,再进行循环遍历,能从剩下中的元素中找到"最大值" 跟最后相应的位置交换。
例如上图,通过一次循环找到最大数字17位置的下标,将其与最后一个数字进行交换,然后排除最后一个数字。重复上述操作,使得该区间不断缩小,直至数组有序。
代码实现:
void swap(int *pa,int *pb){
int t = *pa;
*pa = *pb;
*pb = t;
}
void choice_sort(int arr[],size_t n){
int i,j;
for(i=0;i<n-1;i++){
int m = 0;
for(j=1;j<n-i;j++){
if(arr[m] < arr[j]){
m = j;
}
}
if(m != n-1-i){
//如果m记录的下标值刚好为最后一个位置的下标,则不进行交换,当然这个if语句可以省略
swap(&arr[m],&arr[n-1-i]);
}
}
}
3. 插入排序
插入排序的思路如下(直接插入):
- 主要的实现思想是将数据按照一定的顺序一个一个的插入到有序的表中,最终得到的序列就是已经排序好的数据。
- 从第二个元素开始往前插入,插入之后保持有序。
- 把一个元素插入到前面的区间,插入之后使包含该元素的整个区间都有序
代码实现:
void insert_sort(int arr[],size_t n){
int i,j;
for(i=1;i<n;i++){
//数组第一个数字默认有序,所以从一个数字开始排序
int key = arr[i]; //保存该数字到key
for(j=i-1;j>=0 && key < arr[j];--j){
//往前判断,如果前面的数值比key大,则将该数字放到当前位置,然后再往前判断,直至找到一个比它要小或者等于它的一个数值,或者已经将所有的数值往前移位,则跳出循环
arr[j+1] = arr[j];
}
//将key值插入到当前数值的前面,或者插入到最开头的位置
if(j+1 != i){
arr