一、桶排序
注:这里讲到的桶排序,并不是真正意义上的桶排序(简化版),因为真正的桶排序实现远比这个要复杂。
桶排序,就主要看数据的范围。范围有多大,开辟的数组空间就有多大。简单理解就是,用桶去装数。
优点:高效易理解
缺点:空间消耗较大、更适合数据集中的情况(且只适用于int整型)
//桶排序
//例子:5个<=10的随机数,按从大到小的顺序排序
#include<stdio.h>
#include<stdlib.h>
#define N 11
int main()
{
int arr[N] = {0};
for(int i = 0; i < 5; i++)
{
arr[rand()%10+1]++;//把随机数装进“桶”里
}
for(int i = N-1; i >= 0; i--)
{
if(arr[i] == 0)
continue;
for(int j = 0; j < arr[i]; j++)//“桶”里有几个数就重复打印几遍
printf("%d ", i);
}
return 0;
}
二、冒泡排序
冒泡排序,它弥补了桶排序的不足:节约了空间、适用多种数据类型(用结构体)。
但是它的时间复杂度很高,达到了O(n*n),它适合数据不多的情况。
//冒泡排序
//基本思想:每次比较两个相邻的元素,如果顺序就交换位置
//例子:12 35 99 18 76,从大到小排序
#include<stdio.h>
int main()
{
int arr[5], sum;
for(int i = 0;i < 5; i++)
scanf("%d", &arr[i]);
for(int i = 0;i < 5-1; i++)//有n个数就需要走n-1趟 ,每趟确定最后一个数的位置(最后一个数归位)
{
for(int j = 0;j < 5-i; j++)//每趟,
{
if(arr[j] < arr[j+1])//与相邻的数进行比较
{
sum = arr[j];
arr[j] = arr[j+1];
arr[j+1] = sum;
}
}
}
for(int i = 0;i < 5; i++)
{
printf("%d ",arr[i]);
}
return 0;
}
三、快速排序
快速排序,见名思意,是一个比较高效的算法。它的核心思想是 分治 。
它会要找一个基准数,简单的来说是参考数(一般取第一个数或者是最后一个数),然后对剩余元素进行排序,大于基准数的放在右边,小于基准数的放在左边(顺序默认从小到大),再把基准数归位,接着再对左、右边部分进行类似操作,直至全部排序完。
特点:每一轮都会把基准数归位,
它的平均时间复杂度为O(NlogN),但是,最差的时间复杂度与冒泡排序一样为O(N*N)
//快速排序
//例:给定 6 1 2 7 9 3 4 5 10 8,现在要求用快排给他们排序(从小到大)
#include<stdio.h>
void q_sort(int *arr, int start, int end)
{
int i, j, temp, t;
if(start > end)
return;
temp = arr[start];//选定基准数
i = start;
j = end;
while(i!=j)
{
//从右往左找,特别注意!!!
//因为当只有两个数需要排序时,也就不至于一开始就出现因为i==j而退出的情况了
while(arr[j] >= temp && i < j)
j--;
while(arr[i] <= temp && i < j)
i++;
if(i < j)
{
t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}
//基准数归位
arr[start] = arr[i];
arr[i] = temp;
q_sort(arr, start, i-1);//对左边进行排序
q_sort(arr, i+1, end);//对右边进行排序
}
int main()
{
int arr[10];
for(int i = 0;i < 10; i++)
scanf("%d", &arr[i]);
q_sort(arr, 0, 10-1);
for(int i = 0;i < 10; i++)
printf("%d ",arr[i]);
printf("\n");
return 0;
}