zoukankan      html  css  js  c++  java
  • 计数排序

    1 计数排序 不基于元素之间的比较

    2 计数排序假设n个输入元素中的每一个元素介于0 到 K 之间的整数

    3 计数排序的基本思想是,对于每一个元素x,从n个元素中统计出小于x的个数

       EX:如果有17个元素小于x, 那么x的位置可确定为第18个位置(对于几个元素相同时,需要对方法做略微修改)

    4 计数排序通常的实现方式

      a.  找出n个元素中最大值key,确定一个辅助数组,数组大小为key+1 (+1 考虑了元素0)

          b.  统计每个元素的个数(0 一直到 key)

          c.  统计每个元素x在n个元素中,小于或等于x的个数,累加x元素之前的每个元素个数

         EX:假设为x=2,n个元素中有两个0、三个1 ,那么小于x的就有5个元素,那么x的位置为第六个位置(只有一个2的元素的情况)

        d. 根据上述统计出的信息,进行排序

    5 计数排序的时间代价是Θ(n+k),n为数据规模,k为允许的最大整数,优于比较排序算法的下界Ω(nlgn)

    6 计数排序的一个重要性质是 稳定性,排序后具有相同值的元素在数组中的相对顺序与原先数组的顺序相同

        EX:假设数组中有两个3分别标记为a、b, 如果排序前标记为a的3先出现 ,那么排序后标记为a的3依然先出现

     1 #include <iostream>
     2 #include <crtdbg.h>
     3 #include <cstring>
     4 using namespace std;
     5 
     6 //计数排序基于一个前提:待排序的n个元素是介于 0~key 之间的整数
     7 //array待排序数组,result存储排序结果的数组,key为array的最大值
     8 void CountingSort(int array[], int result[], int size)
     9 {
    10     int key = array[0];//找出最大值,通常key值是已知的(前提),此处只是为了节省空间
    11     for(int i=1; i<size; ++i)
    12     {
    13         if (key < array[i])
    14         {
    15             key = array[i];
    16         }
    17     }
    18 
    19     //分配临时的辅助数组,+1是因为考虑元素0
    20     //初始化可以通过for循环初始化,或者分配时int *p = new int[key+1](),此处使用memset
    21     int *p = new int[key+1];  
    22     memset(p, 0, (key+1)*sizeof(p[0]));
    23 
    24     //数组p使用元素大小做为下标,统计array的每个元素的个数
    25     for(int i=0; i<size; ++i)
    26     {
    27         int position = array[i];  //获取元素的位置
    28         p[position] = p[position] + 1;
    29     }
    30 
    31     //数组p 记录每个元素在数组array中 小于或等于该元素的个数 
    32     //比如小于等于 2 的元素个数为4, 小于等于 3 的个数为 7
    33     for (int i=1; i<=key; ++i)
    34     {
    35         p[i] = p[i]+p[i-1];
    36     }
    37 
    38     //根据上述获取的信息,进行排序
    39     //例如数组array有4个元素小于或等于2,那么2的位置为第4个或者第4个之前的位置
    40     for (int i=size-1; i>=0; --i)//此处为保证稳定性,从size-1 向 0 迭代 
    41     {
    42         int position = p[array[i]]; //获取数组array[i]的位置
    43         result[position-1] = array[i]; //放到正确的位置
    44         p[array[i]]= p[array[i]] - 1;  //更新该元素的个数
    45     }
    46 
    47     delete [] p;
    48 }
    49 void main()
    50 {
    51     //检测是否有内存泄露 需要加头文件#include <crtdbg.h>
    52     _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    53 
    54     int Array[8] = {2, 5, 3, 0, 2, 3, 0, 3};
    55     int Result[8] = {0};
    56 
    57     CountingSort(Array, Result, sizeof(Array)/sizeof(Array[0]));
    58 
    59     for (int i= 0 ; i < 8; ++i)
    60     {
    61         cout << Result[i] << "
    ";
    62     }
    63 
    64     system("pause");
    65 }

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

  • 相关阅读:
    java学习
    瓜娃《guava》api快速入门
    List,set,Map 的用法和区别
    css selector
    字节流与字符流区别
    jsoup的elements类
    javaio-printwriter
    map遍历的四种方法
    kafka集群和zookeeper集群的部署,kafka的java代码示例
    Ubuntu12.04安装中文字体(转)
  • 原文地址:https://www.cnblogs.com/sevenPP/p/3641912.html
Copyright © 2011-2022 走看看