zoukankan      html  css  js  c++  java
  • 非比较排序

    非比较排序

    一、什么是非比较排序


    区别传统的比较算法,不通过其中两个数的大小直接比较,来排序整个数列

    二、具体实现


    1、计数排序


    很好理解,就是对应每个数我们统计每个数字出现的次数,然后用一个直接定址的哈希表来存放数据,在通过遍历这个哈希表,进而就可以排好序了

    (1)代码实现

     1 void CountSort(int arr[], int size)
     2 {
     3 assert(arr);
     4 
     5 int min = arr[0], max = arr[0];//统计最大和最小的数
     6 for (int i = 0; i < size; i++)
     7 {
     8 if (arr[i] > max)
     9 {
    10 max = arr[i];
    11 }
    12 if (arr[i] < min)
    13 {
    14 min = arr[i];
    15 }
    16 }
    17 
    18 int range = max - min + 1;//开空间的大小
    19 int* count = new int[range]();
    20 
    21 memset(count, 0, sizeof(int)*range);
    22 //统计次数
    23 for (int i = 0; i < size; i++)
    24 {
    25 count[arr[i] - min]++;
    26 }
    27 
    28 size_t index = 0;
    29 for (int i = 0; i < range; i++)
    30 {
    31 while (count[i]-- != 0)
    32 {
    33 arr[index++] = i + min;
    34 }
    35 }
    36 }


    (2)优缺点
    优点:对于密集无重复的序列,可以使用位图来节省空间
    缺点:比较浪费空间,不能排序一些负数(通过一些特殊的处理其实是可以做到的,但是比较麻烦)

    2、基数排序


    包括LSD( Least Significant Digit first最低位优先)、MSD(Most Significant Digit first最高位优先)

    其实两者的道理都是想通的,这里主要来讲解和实现LSD

    (1)什么是基数排序
    这里的基数是指数据的位数(个位、十位、百位...),LSD便是从个位到最高位(例如:最大的数为12345,那么最高位便为万位),每次由高从低到高进行排序。排完最高为之后,整个序列就变得有序了

    思考:为什么排完最高位之后整个序列就变得有序了?

    这是因为的由低位到高位进行排序,那么通过上一次的排序影响下一次的排序、简单的来说,就是处理千位的时候,对百位、十位、个位排好序的并没有影响,低位小的数据一定会在前面先处理掉,由相对位置来决定的·

    (2)具体实现

    void LSDSort(int arr[], int size)
    {
    assert(arr);
    
    int maxRadix = GetMaxRadix(arr, size);
    int count[10] = { 0 };
    int start[10] = { 0 };
    int* bucket = new int[size];
    //有点像矩阵的那一块
    int radix = 1;
    for (int i = 0; i < maxRadix; ++i)//控制位数
    {
    memset(count, 0, sizeof(int) * 10);
    
    
    for (int j = 0; j < size; ++j)//统计对应的每次的低位相同的数字出现的次数
    {
    int num = (arr[j] / radix) % 10;//依次获取每一位的数字
    count[num]++;
    }
    start[0] = 0;//用来标记每相同低位的值到底有多少个,然后进行直接定位
    int index = 1;
    while (index < 10)
    {
    start[index] = start[index - 1] + count[index - 1];
    ++index;
    }
    for (int k = 0; k < size; ++k)
    {
    int num = (arr[k] / radix) % 10;
    //关键
    bucket[start[num]++] = arr[k];//通过辅助的数组start直接进行定位
    }
    radix *= 10;
    memcpy(arr, bucket, sizeof(int)*size);
    
    }
    delete[] bucket;
    }
    

      

  • 相关阅读:
    微信开发-微信支付(v3.3以上版本)
    微信开发-微信一般帮助类
    公司级平台_IProgram_Model
    公司级平台-IProgram_BLL
    公司级平台-IProgram-DAL
    公司级平台-IProgram-IBaseProgram
    公司级平台 -接口层IProgram
    asp mvc 中重写JsonResult,解决Json返回值序列化问题
    GPIO位带操作点亮LED,且使用按键控制开关
    按键检测GPIO输入
  • 原文地址:https://www.cnblogs.com/muzhongjiang/p/12834276.html
Copyright © 2011-2022 走看看