计数排序
定义:计数排序是一种稳定的线性时间排序算法,原理是使用一个额外的数组,其中第i个元素是待排序数组中值等于i的元素的个数。
实现步骤:
(1)找出待排序的数组中最大和最小的元素
(2)统计数组中每个值为i的元素出现的次数,存入数组C的第i项
(3)对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)
(4)反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1
图引用自菜鸟教程:
#include<stdio.h>
#include<stdlib.h>
#define MAXNUM 10
void main()
{
void CountSort(int data[],int n);
int i,data[MAXNUM];
for(i=0;i<MAXNUM;i++)
scanf("%d",&data[i]);
CountSort(data,MAXNUM);
for(i=0;i<MAXNUM;i++)
printf("%d ",data[i]);
printf("\n");
}
void CountSort(int data[],int n)
{
int i,j,count,*data_p,temp;
data_p=(int*)malloc(sizeof(int)*n);
for(i=0;i<n;i++)//初始化data_p
data_p[i]=0;
for(i=0;i<n;i++)
{
count=0;
for(j=0;j<n;j++)//扫描待排序数组
if(data[j]<data[i])//统计比data[i]值小的值的个数
count++;
while(data_p[count]!=0)//对于相等非0的数据,应向后措一位。数据为0时,因数组data_p被初始化为0,故不受影响。
/* 注意此处应使用while循环进行判断,若用if条件则超过三个重复值后有0出现 */
count++;
data_p[count]=data[i];//存放到data_p中的对应位置
}
//用于检查当有多个数相同时的情况
i=0,j=n;
while(i<j)
{
if(data_p[i]==0)
{
temp=i-1;
data_p[i]=data_p[temp];
}//of if
i++;
}//of while
for(i=0;i<n;i++)//把排序完的数据复制到data中
data[i]=data_p[i];
free(data_p);//释放data_p
}
时间复杂度
计数排序的时间复杂度为O(n+k)。其中n为待排序元素个数,k为待排序元素最大值
空间复杂度
计数排序的空间复杂度为n+O(k)。其中n为待排序元素个数,k为待排序元素最大值
优缺点
优点:速度快。
缺点:需要提前知道待排序元素最大值,需要大量内存消耗。
冒泡排序
定义:是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
实现步骤:
(1)比较相邻元素,若前一个元素比后一个元素大,则交换位置
(2)将每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数
(3)、针对所有的元素重复以上的步骤,除了最后一个
(4)、重复以上三个步骤,知道排序完成
#include<iostream>
#include <stdio.h>
#define ARR_LEN 255 /*数组长度上限*/
/* 冒泡排序 */
/* 1. 从当前元素起,向后依次比较每一对相邻元素,若逆序则交换 */
/* 2. 对所有元素均重复以上步骤,直至最后一个元素 */
/* elemType arr[]: 排序目标数组; int len: 元素个数 */
void bubbleSort (elemType arr[], int len) {
int temp;
int i, j;
for (i=0; i<len-1; i++) /* 外循环为排序趟数,len个数进行len-1趟 */
for (j=0; j<len-1-i; j++) { /* 内循环为每趟比较的次数,第i趟比较len-i次 */
if (arr[j] > arr[j+1]) { /* 相邻元素比较,若逆序则交换(升序为左大于右,降序反之) */
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
int main (void) {
int arr[ARR_LEN] = {3,5,1,-7,4,9,-6,8,10,4};
int len = 10;
int i;
bubbleSort (arr, len);
for (i=0; i<len; i++)
cout<<arr[i];
putchar ('\n');
return 0;
}
时间复杂度
最优的时间复杂度为:O( n^2 ) ;
最差的时间复杂度为:O( n^2 );
平均的时间复杂度为:O( n^2 );
空间复杂度
空间复杂度就是在交换元素时那个临时变量所占的内存空间;
最优的空间复杂度就是开始元素顺序已经排好了,则空间复杂度为:0;
最差的空间复杂度就是开始元素逆序排序了,则空间复杂度为:O(n);
平均的空间复杂度为:O(1);
最优时间复杂度 n;
优点:比较简单,空间复杂度较低,是稳定的;
缺点:时间复杂度太高,效率慢;