我们常用的排序冒泡排序 O(n^2); 快速排序O(nlogn);堆排序O(nlogn);选择排序O(n^2);
我们常用的排序都不符合时间复杂度的要求;
经常听说一个说法 用空间代替时间
现在要排序的数组为数组 a;例如a数组里面有 1,1,2,2,3,3,2,2,5,5………等等很多无序的数字
那么我们申请一个数组b,假设a数组当中的数字都在100一下;
那么我们的b数组只要申请b【100】就可以了
void SortByN(int a[], int length)
{
if (a == NULL || length < 0)
{
return;
}
//重新申请一个数组
const int N =200;
int b[N];
//把新申请的数组全部初始化为0
for (int i = 0; i < N; ++i)
{
b[i] = 0;
}
//遍历a数组
for (int i = 0; i < length; ++i)
{
//例如:a[0] = 10;那么b[key] = b[10] = 1;表示有一个10; a[4] = 10;
//那么b[key] = b[10] = 1+1 = 2,表示此时有两个10;
int key = a[i];
++b[key];
//意思就是b数组里面存放的是a数组中某个元素的个数,b[10]表示在a数
//组当中10出现的次数,b[0]表示0在a数组当中出现的次数
}
int index = 0;
for (int i = 0; i < N; ++i)
{
//如果b[0] = 0;表示a数组当中没有0;那么不执行这个循环;例如这里a是一个年龄数组,假设最小的年龄是18
//那么b[0] -- b[17]都是等于0;那么第二个循环都不执行,第一个循环执行,i加到了18;b[18]=2;
//那么a数组当中有两个18;而且这两个18就是最小的数字,那么a[0] = 18; a[1] = 18;
for (int j = 0; j < b[i];++j)
{
a[index] = i;
++index;
}
}
}
b数组的大小是一个常量,所以遍历b数组的时间复杂度是O(1);
完整测试代码:
// SortByN.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <string.h>
using namespace std;
void SortByN(int a[], int length)
{
if (a == NULL || length < 0)
{
return;
}
//重新申请一个数组
const int N =200;
int b[N];
//把新申请的数组全部初始化为0
for (int i = 0; i < N; ++i)
{
b[i] = 0;
}
//遍历a数组
for (int i = 0; i < length; ++i)
{
//例如:a[0] = 10;那么b[key] = b[10] = 1;表示有一个10; a[4] = 10;那么b[key] = b[10] = 1+1 = 2,表示此时有两个10;
int key = a[i];
++b[key];
//意思就是b数组里面存放的是a数组中某个元素的个数,b[10]表示在a数组当中10出现的次数,b[0]表示0在a数组当中出现的次数
}
int index = 0;
for (int i = 0; i < N; ++i)
{
for (int j = 0; j < b[i];++j)//如果b[0] = 0;表示a数组当中没有0;那么不执行这个循环;例如这里a是一个年龄数组,假设最小的年龄是18
//那么第一个循环b[0] -- b[17]都是等于0;那么第二个循环都不执行,第一个循环执行,i加到了18;b[18]=2;那么a数组当中有两个18;而且这两个
//18就是最小的数字,那么a[0] = 18; a[1] = 18;
{
a[index] = i;
++index;
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int a[10] = {2,2,3,3,111,111,33,44,55,55};
for (int i = 0; i < 10; ++i)
{
cout<<a[i]<<" ";
}
SortByN(a,10);
cout<<"排序后的数组为:"<<endl;
for (int i = 0; i < 10; ++i)
{
cout<<a[i]<<" ";
}
getchar();
return 0;
}