排序算法(七)---- 非比较排序

一.计数排序
顾名思义,通过记录原序列中的每个数据出现的次数,然后将其保存在辅助空间的对应位置(位置=当前数据-最小数据),通过分析辅助空间和原序列,可以将原序列变成有序序列
算法如下:
void CountSort(int arr[],int size)
{
       int i=0;
       int max=arr[0];
       int min=arr[0];
       for(i=1;imax)
                     max=arr[i];
              if(arr[i]=0;i--)//从右到左,保证算法的稳定性
       {
              tmp[count[arr[i]]-1]=arr[i];
              count[arr[i]]--;
       }

       memcpy(arr,tmp,size*sizeof(arr[0]));
}

时间复杂度为O(size+len),空间复杂度为O(len),算法稳定
通过上面的分析,很容易发现计数排序适用于数据密集,有大量数据重复的序列

二. 基数排序
参考博客: http://www.cnblogs.com/Braveliu/archive/2013/01/21/2870201.html
对于基数排序,也叫多关键码排序,在对指定数据进行排序之前,将这些数据的多个关键字从高到低进行划分,由此排序方式也就分为最高位优先MSD和最低位优先LSD两种方式
MSD,LSD两种方式的基本方法:
①统计每个桶中的数据个数;
②统计每个桶的起始地址(或者末尾地址)
③将数据放至桶中;
④回收桶中的数据;
⑤根据下一个关键码进行排序,重复上述;
而对于MSD方式,则可以在将数据放至桶中之后,对这个桶中的数据重新根据下一个关键码进行划分子桶,最后进行统一回收
算法如下:
①MSD
int Pow(int x,int y)
{
       int ret=1;
       while(y--)
       {
              ret*=x;
       }

       return ret;
}

void BaseSort_MSD(int arr[],int size,int n)
{
       int count[10];
       memset(count,0,10*sizeof(count[0]));

       int i=0;
       for(i=0;i=0;i--)//从右向左,保证稳定性
       {
              bucket[count[arr[i]/Pow(10,n-1)]-1]=arr[i];
              count[arr[i]/Pow(10,n-1)]--;
       }

       memcpy(arr,bucket,size*sizeof(arr[0]));
       delete[] bucket;

       for(i=0;i<10;i++)
       {
              size=count[i+1]-count[i];
              if(size>1)
                     BaseSort_MSD(arr,size,n-1);
       }
}

②LSD
int Pow(int x,int y)
{
       int ret=1;
       while(y--)
       {
              ret*=x;
       }

       return ret;
}

void BaseSort_LSD(int arr[],int size,int n)
{
       int count[10];
       int* bucket=new int[size];
       int i=0;
       int m=1;

       while(m<=n)
       {
              memset(count,0,sizeof(count));
              for(i=0;i=0;i--)//从右向左,保证稳定性
              {
                     bucket[count[arr[i]%Pow(10,m)/Pow(10,m-1)]-1]=arr[i];
                     count[arr[i]%Pow(10,m)/Pow(10,m-1)]--;
              }

              memcpy(arr,bucket,size*sizeof(arr[0]));
              m++;
       }

       delete[] bucket;

}

对于基数排序,时间复杂度为O(N*基数位数),空间复杂度为O(N),且算法稳定
通过上述分析,可以发现基数排序适用于具有多个关键码的数据排序,而且这些数据不一定是数字

附上一张图(所有排序算法的时间复杂度,空间复杂度以及稳定性)
排序算法(七)---- 非比较排序_第1张图片

你可能感兴趣的:(数据结构,非比较排序,计数排序,基数排序,算法)