zoukankan      html  css  js  c++  java
  • 基数排序(RadixSort)

    1 基数排序的特点是研究多个关键字key,且多个key之间有权重之分,

       或者可把单个key建模为含有多个key的排序

       而计数排序、桶排序始终只有个一个key,或者说围绕着一个比较规则

       Ex:比较年月日,先比较年份,如果相同,比较月份,如果还是相同,就比较日

    2 根据首先选择有效位的不同,分为两种

       A. 先比较最高有效位,然后在比较次高位的有效位,以此类推进行比较MSD(Most Significant Dight)

         假如有189,321,312,167 需要考虑高有效位相同的情况与不同的情况

           最高位不同:直接分出大小,并且需要记住312与321 > 比189,167大 

           最高位相同:比较十位,并且根据上述记录只比较312与321之间的十位数,否则排序是不稳定的

       B. 先比较最低有效位,然后在比较次低位的有效位,以此类推进行比较LSD(Least Significant Dight)

           无需考虑MSD排序遇到的问题,直接对每个位数排序即可

           注意:每次排序只针对当前位数(辅助排序函数必须是基于稳定的)

    3 可以使用基数排序对一些位数有限的十进制数排序(十进制整数每位固定大小0~9)

    4 基数排序时间代价 O(d(n+k))(前提是辅助函数为计数排序的情况下)

       d为关键值key的位数的个数,每位排序执行计数排序需要O(n+k)

      1 #include <iostream>
      2 #include <crtdbg.h>
      3 #include <cstring>
      4 using namespace std;
      5 
      6 const int SIZE = 10;  //n的大小
      7 const int K = 1000;   //允许的最大整数
      8 enum numberBit
      9 {
     10     GeWei     = 1,
     11     ShiWei    = 10,
     12     BaiWei    = 100,
     13     QianWei   = 1000,
     14 };
     15 //获取当前位数,d表示位数
     16 int GetData(const int data, int d)
     17 {
     18     int tmp = 0;
     19     switch(d)
     20     {
     21     case GeWei:
     22         {
     23             tmp = data%10;
     24         }
     25         break;
     26     case ShiWei:
     27         {
     28             tmp = data%100;
     29             tmp = tmp/10;
     30         }
     31         break;
     32     case BaiWei:
     33         {
     34             tmp = data%1000;
     35             tmp = tmp/100;
     36         }
     37         break;
     38     case QianWei:
     39         {
     40             tmp = data/1000; //允许最大值为1000
     41         }
     42         break;
     43     default:
     44         {
     45             cout <<"wrong number, which big then k";
     46             return -1;
     47         }
     48         break;
     49     }
     50     return tmp;
     51 }
     52 //计数排序, d为当前位数
     53 void CountingSort(int array[], int size, int d)
     54 {
     55     //建立辅助数组pCount大小固定为10(0~9),用来存储统计的元素信息
     56     int *pCount = new int[10];   
     57     memset(pCount, 0, (10)*sizeof(pCount[0]));
     58      
     59     //建立辅助数组result存储结果
     60     int *result = new int[size]; 
     61     memset(result, 0, size*sizeof(result[0]));
     62 
     63     //数组p使用元素大小做为下标,统计array的每个元素的个数
     64     for(int i=0; i<10; ++i)
     65     {
     66         int position = GetData(array[i], d);  //获取元素的位置
     67         pCount[position] = pCount[position] + 1;
     68     }
     69 
     70     //数组p 记录每个元素x在数组array中 小于或等于x的个数 
     71     //比如个位数时:小于等于4 的为元素 为3个(0, 1000, 83) 
     72     for (int i=1; i<=9; ++i)
     73     {
     74         pCount[i] = pCount[i]+pCount[i-1];
     75     }
     76 
     77     //根据上述获取的信息,进行排序
     78     //比如个位数时:小于等于4的为元素为3个(0, 1000, 83),4的位置为第4个 
     79     for (int i=size-1; i>=0; --i)//此处为保证稳定性,从size-1 向 0 迭代 
     80     {
     81         int data = GetData(array[i], d);
     82         int position = pCount[data];      //获取数组array[i]的位置
     83         result[position-1] = array[i];    //放到正确的位置
     84         pCount[data]= pCount[data] - 1;   //更新该元素的个数
     85     }
     86     //把结果存储到最初的数组array
     87     for (int i=0; i<size; ++i)
     88     {
     89         array[i] = result[i];
     90     }
     91     delete [] pCount;
     92     delete [] result;
     93 }
     94 //基数排序,k为允许的最大整数
     95 void RadixSort(int array[], int size, int k)
     96 {
     97     //选择稳定排序即可,计数排序或者桶排序(桶排序具体实现请转到上一节)
     98     for (int i=1; i<=k; i=i*10) //i表示位数,从低有效位到高有效位 LSD 
     99     {
    100         CountingSort(array, size, i);    //计数排序                                        
    101     }
    102 }
    103 void main()
    104 {
    105     //检测是否有内存泄露 需要加头文件#include <crtdbg.h>
    106     _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    107 
    108     int array[SIZE] = {328, 4, 456, 656, 0, 1000, 439, 725, 328, 83,};
    109 
    110     RadixSort(array, SIZE, K);
    111 
    112     for (int i=0; i<SIZE; ++i)
    113     {
    114         cout << array[i] << endl;
    115     }
    116 
    117     system("pause");
    118 }

    (转载请注明作者和出处^_*  Seven++ http://www.cnblogs.com/sevenPP/  )

  • 相关阅读:
    在IE中下载Office2007文件时在对话框中下载文件变成ZIP文件的问题
    异常:tomcat与windows时间不同步
    centos 解决"不在 sudoers 文件中。此事将被报告"的问题
    linux device drivers
    linux device drivers
    linux device drivers
    Source Insight 空格和Tab出现乱码
    光和颜色
    RTOS Thread stack and MSP/PSP registers in ARM Cortex-M3
    Keil MDK编译出现Error: L6405E
  • 原文地址:https://www.cnblogs.com/sevenPP/p/3648882.html
Copyright © 2011-2022 走看看