常见的时间复杂度,按数量级递增排列依次为:常数阶O(1)、对数阶O(log2n)、线性阶O(n)、线性对数阶O(nlog2n)、平方阶O(n2)、立方阶O(n3)、k次方阶O(nk)、指数阶O(2n)。常见的算法时间复杂度由小到大依次为:
c < log2N < n < n * Log2N < n^2 < n^3 < 2^n < 3^n < n!
冒泡排序
两两比较
两个数字比较
int n = list.size();
for (int i = 0; i < n - 1; ++i)
{
for (int j = i + 1; j < n; ++j)
{
if (list[i] > list[j])
swap(list[i], list[j]);
}
}
选择排序
选一个最小的,放到最前面。
(优化:可以同时选最大的放最右边)
void SelectSort(){
for (int i = 0; i < N-1; ++i)
{
int pos =i;
for (int j = i+1; j < N; ++j)
{
if (sque[j]<sque[pos])
{
pos=j;
}
}
if (pos!=i)
{
int temp=sque[pos];
sque[pos]=sque[i];
sque[i]=temp;
}
}
}
插入排序
和打扑克牌一样,抽牌后从后面一个个比,大了就放进去。
(优化:用链表排(不移动),带多个元素排,希尔排序)
void insert_sort(int arr[], int len)
{
for (int i = 1; i < len; ++i)
{
if (arr[i] < arr[i - 1]) {
int temp = arr[i];
for (int j=i-1 ; j>=0 && arr[j]>temp ;--j)
{
arr[i] = arr[j];//交换位置
}
arr[i] = temp;
}
}
}
希尔排序
1、分2组,排列个数÷2减1 ;
2、两个组对比,小的放前面的组,list1[1]和list2[1]对比交换;
3、分2组,排列个数÷2再÷2减1 ;
最后就是插入排序了
int shsort(int s[], int n) /* 自定义函数 shsort()*/
{
int i,j,d;
d=n/2; /*确定固定增虽值*/
while(d>=1)
{
for(i=d+1;i<=n;i++)/*数组下标从d+1开始进行直接插入排序*/
{
s[0]=s[i]; /*设置监视哨*/
j=i-d; /*确定要进行比较的元素的最右边位置*/
while((j>0)&&(s[0]<s[j]))
{
s[j+d]=s[j]; /*数据右移*/
j=j-d; /*向左移d个位置V*/
}
s[j + d]=s[0]; /*在确定的位罝插入s[i]*/
}
d = d/2; /*增里变为原来的一半*/
}
return 0;
}
快速排序
1、随机取一个值,再取 值位置和最大size位置的指针
取一个比它小的值放在它的值位置上,或者大的,
2、两个指针逼近重叠就排好一个,再取左边一个值循环1操作
3、区间小于2个元素就不用排了
int qusort(int s[],int start,int end) //自定义函数 qusort()
{
int i,j; //定义变量为基本整型
i=start; //将每组首个元素赋给i
j = end; //将每组末尾元素赋给j
s[0]=s[start]; //设置基准值
while(i<j)
{
while(i<j&&s[0]<s[j])
j--; //位置左移
if(i<j)
{
s[i]=s[j]; //将s[j]放到s[i]的位置上
i++; //位置右移
}
while(i<j&&s[i]<=s[0])
i++; //位置左移
if(i<j)
{
s[j]=s[i]; //将大于基准值的s[j]放到s[i]位置
j--; //位置左移
}
}
s[i]=s[0]; //将基准值放入指定位置
if (start<i)
qusort(s,start,j-1);//对分割出的部分递归调用qusort()函数
if (i<end)
qusort(s,j+1,end);
return 0;
}
归并排列
void merge(int arr[], int start, int mid, int end) {
int result[ArrLen];
int k = 0;
int i = start;
int j = mid + 1;
while (i <= mid && j <= end) {
if (arr[i] < arr[j]){
result[k++] = arr[i++];
}
else{
result[k++] = arr[j++];
}
}
if (i == mid + 1) {
while(j <= end)
result[k++] = arr[j++];
}
if (j == end + 1) {
while (i <= mid)
result[k++] = arr[i++];
}
for (j = 0, i = start ; j < k; i++, j++) {
arr[i] = result[j];
}
}
void mergeSort(int arr[], int start, int end) {
if (start >= end)
return;
int mid = ( start + end ) / 2;
mergeSort(arr, start, mid);
mergeSort(arr, mid + 1, end);
merge(arr, start, mid, end);
}
堆排序
要完整的二叉树(满的,如果有分支要从左边)
代码百度
计数排序
1、记下每个数字出现的次数
2、排列回去.
void coutSort(int* data, int length)
{
if (data == nullptr || length <= 0)
return;
//确定数列最大值
int max = data[0];
for (int i = 1; i < length; ++i)
{
if (data[i] > max)
max = data[i];
}
// 确定统计数组长度并进行初始化
int* coutData = new int[max + 1];
for (int i = 0; i <= max; ++i)
coutData[i] = 0;
// 遍历数组,统计每个数出现的次数
for (int i = 0; i < length; ++i)
++coutData[data[i]];
// 排序数组,某个数出现了几次,便在data里累计输出几次
int index = 0;
for (int i = 0; i <= max; ++i)
{
for (int j = 0; j < coutData[i]; ++j)
{
data[index++] = i;
}
}
}
桶排序
void Insert(vector<double> & bkt, double num) {
for (vector<double>::iterator p = bkt.begin(); p != bkt.end(); ++p)
if (*p > num) {
bkt.insert(p, num);
return ;
}
bkt.push_back(num); //没有找到,就放最后
}
void BucketSort(double * const begin, double * const end) { //假设输入数据都是小数[0,1)
int n = end - begin;
int i;
vector<vector<double>*> bucket(n); //为什么是n个桶,应该和hash一个原理
for (i = 0; i < n; ++i)
bucket[i] = new vector<double>;
for (i = 0; i < n; ++i) { //按顺序插入到桶中
Insert(*bucket[static_cast<int>(*(begin + i) * n)], *(begin + i));
}
int j = 0, k = 0;
for (i = 0; i < n; ++i) {
while (k >= bucket[j]->size()) { //如果出现连续的空桶
++j;
k = 0;
}
*(begin + i) = (*bucket[j])[k++];
}
for (i = 0; i < n; ++i)
delete bucket[i];
}
基数排序
// 获取数组arr中最大值,arr-待排序的数组,len-数组arr的长度。
int arrmax(int *arr,unsigned int len)
{
int ii,imax;
imax=arr[0];
for (ii=1;ii<len;ii++)
if (arr[ii]>imax) imax=arr[ii];
return imax;
}
// 对数组arr按指数位进行排序。
// arr-待排序的数组,len-数组arr的长度。
// exp-排序指数,exp=1:按个位排序;exp=10:按十位排序;......
void _radixsort(int *arr,unsigned int len,unsigned int exp)
{
int ii;
int result[len]; // 存放从桶中收集后数据的临时数组。
int buckets[10]={0}; // 初始化10个桶。
// 遍历arr,将数据出现的次数存储在buckets中。
for (ii=0;ii<len;ii++)
buckets[(arr[ii]/exp)%10]++;
// 调整buckets各元素的值,调整后的值就是arr中元素在result中的位置。
for (ii=1;ii<10;ii++)
buckets[ii]=buckets[ii]+buckets[ii-1];
// 将arr中的元素填充到result中。
for (ii=len-1;ii>=0;ii--)
{
int iexp=(arr[ii]/exp)%10;
result[buckets[iexp]-1]=arr[ii];
buckets[iexp]--;
}
// 将排序好的数组result复制到数组arr中。
memcpy(arr,result,len*sizeof(int));
}
// 基数排序主函数,arr-待排序的数组,len-数组arr的长度。
void radixsort(int *arr,unsigned int len)
{
int imax=arrmax(arr,len); // 获取数组arr中的最大值。
int iexp; // 排序指数,iexp=1:按个位排序;iexp=10:按十位排序;......
// 从个位开始,对数组arr按指数位进行排序。
for (iexp=1;imax/iexp>0;iexp=iexp*10)
{
_radixsort(arr,len,iexp);
int yy; printf("exp=%-5d ",iexp); for (yy=0;yy<len;yy++) printf("%2d ",arr[yy]); printf("\n");
}
}
笔记收藏1041449625