更多精彩内容,欢迎关注:

视频号
视频号

抖音
抖音

快手
快手

微博
微博

如何按照计数进行排序

文档

如何按照计数进行排序

计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。
推荐度:
导读计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。
.example-btn{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.example-btn:hover{color:#fff;background-color:#47a447;border-color:#398439}.example-btn:active{background-image:none}div.example{width:98%;color:#000;background-color:#f6f4f0;background-color:#d0e69c;background-color:#dcecb5;background-color:#e5eecc;margin:0 0 5px 0;padding:5px;border:1px solid #d4d4d4;background-image:-webkit-linear-gradient(#fff,#e5eecc 100px);background-image:linear-gradient(#fff,#e5eecc 100px)}div.example_code{line-height:1.4em;width:98%;background-color:#fff;padding:5px;border:1px solid #d4d4d4;font-size:110%;font-family:Menlo,Monaco,Consolas,"Andale Mono","lucida console","Courier New",monospace;word-break:break-all;word-wrap:break-word}div.example_result{background-color:#fff;padding:4px;border:1px solid #d4d4d4;width:98%}div.code{width:98%;border:1px solid #d4d4d4;background-color:#f6f4f0;color:#444;padding:5px;margin:0}div.code div{font-size:110%}div.code div,div.code p,div.example_code p{font-family:"courier new"}pre{margin:15px auto;font:12px/20px Menlo,Monaco,Consolas,"Andale Mono","lucida console","Courier New",monospace;white-space:pre-wrap;word-break:break-all;word-wrap:break-word;border:1px solid #ddd;border-left-width:4px;padding:10px 15px}

排序算法是《数据结构与算法》中最基本的算法之一。排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。以下是计数排序算法:

计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。

1. 计数排序的特征

当输入的元素是 n 个 0 到 k 之间的整数时,它的运行时间是 Θ(n + k)。计数排序不是比较排序,排序的速度快于任何比较排序算法。

由于用来计数的数组C的长度取决于待排序数组中数据的范围(等于待排序数组的最大值与最小值的差加上1),这使得计数排序对于数据范围很大的数组,需要大量时间和内存。例如:计数排序是用来排序0到100之间的数字的最好的算法,但是它不适合按字母顺序排序人名。但是,计数排序可以用在基数排序中的算法来排序数据范围很大的数组。

通俗地理解,例如有 10 个年龄不同的人,统计出有 8 个人的年龄比 A 小,那 A 的年龄就排在第 9 位,用这个方法可以得到其他每个人的位置,也就排好了序。当然,年龄有重复时需要特殊处理(保证稳定性),这就是为什么最后要反向填充目标数组,以及将每个数字的统计减去 1 的原因。

?算法的步骤如下:

(1)找出待排序的数组中最大和最小的元素(2)统计数组中每个值为i的元素出现的次数,存入数组C的第i项(3)对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)(4)反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去12. 动图演示

代码实现JavaScript 实例 function countingSort(arr, maxValue) {    var bucket = new Array(maxValue+1),        sortedIndex = 0;        arrLen = arr.length,        bucketLen = maxValue + 1;    for (var i = 0; i < arrLen; i++) {        if (!bucket[arr[i]]) {            bucket[arr[i]] = 0;        }        bucket[arr[i]]++;    }    for (var j = 0; j < bucketLen; j++) {        while(bucket[j] > 0) {            arr[sortedIndex++] = j;            bucket[j]--;        }    }    return arr;}Python实例 def countingSort(arr, maxValue):    bucketLen = maxValue+1    bucket = [0]*bucketLen    sortedIndex =0    arrLen = len(arr)    for i in range(arrLen):        if not bucket[arr[i]]:            bucket[arr[i]]=0        bucket[arr[i]]+=1    for j in range(bucketLen):        while bucket[j]>0:            arr[sortedIndex] = j            sortedIndex+=1            bucket[j]-=1    return arrGo实例 func countingSort(arr []int, maxValue int) []int {        bucketLen := maxValue + 1        bucket := make([]int, bucketLen) // 初始为0的数组        sortedIndex := 0        length := len(arr)        for i := 0; i < length; i++ {                bucket[arr[i]] += 1        }        for j := 0; j < bucketLen; j++ {                for bucket[j] > 0 {                        arr[sortedIndex] = j                        sortedIndex += 1                        bucket[j] -= 1                }        }        return arr}Java实例 public class CountingSort implements IArraySort {    @Override    public int[] sort(int[] sourceArray) throws Exception {        // 对 arr 进行拷贝,不改变参数内容        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);        int maxValue = getMaxValue(arr);        return countingSort(arr, maxValue);    }    private int[] countingSort(int[] arr, int maxValue) {        int bucketLen = maxValue + 1;        int[] bucket = new int[bucketLen];        for (int value : arr) {            bucket[value]++;        }        int sortedIndex = 0;        for (int j = 0; j < bucketLen; j++) {            while (bucket[j] > 0) {                arr[sortedIndex++] = j;                bucket[j]--;            }        }        return arr;    }    private int getMaxValue(int[] arr) {        int maxValue = arr[0];        for (int value : arr) {            if (maxValue < value) {                maxValue = value;            }        }        return maxValue;    }}PHP实例 function countingSort($arr, $maxValue = null){    if ($maxValue === null) {        $maxValue = max($arr);    }    for ($m = 0; $m < $maxValue + 1; $m++) {        $bucket[] = null;    }    $arrLen = count($arr);    for ($i = 0; $i < $arrLen; $i++) {        if (!array_key_exists($arr[$i], $bucket)) {            $bucket[$arr[$i]] = 0;        }        $bucket[$arr[$i]]++;    }    $sortedIndex = 0;    foreach ($bucket as $key => $len) {                if($len !== null){            for($j = 0; $j < $len; $j++){                $arr[$sortedIndex++] = $key;            }        }    }    return $arr;}C实例 #include #include #include void print_arr(int *arr, int n) {        int i;        printf("%d", arr[0]);        for (i = 1; i < n; i++)                printf(" %d", arr[i]);        printf(" ");}void counting_sort(int *ini_arr, int *sorted_arr, int n) {        int *count_arr = (int *) malloc(sizeof(int) * 100);        int i, j, k;        for (k = 0; k < 100; k++)                count_arr[k] = 0;        for (i = 0; i < n; i++)                count_arr[ini_arr[i]]++;        for (k = 1; k < 100; k++)                count_arr[k] += count_arr[k - 1];        for (j = n; j > 0; j--)                sorted_arr[--count_arr[ini_arr[j - 1]]] = ini_arr[j - 1];        free(count_arr);}int main(int argc, char **argv) {        int n = 10;        int i;        int *arr = (int *) malloc(sizeof(int) * n);        int *sorted_arr = (int *) malloc(sizeof(int) * n);        srand(time(0));        for (i = 0; i < n; i++)                arr[i] = rand() % 100;        printf("ini_array: ");        print_arr(arr, n);        counting_sort(arr, sorted_arr, n);        printf("sorted_array: ");        print_arr(sorted_arr, n);        free(arr);        free(sorted_arr);        return 0;}

参考地址:

https://github.com/hustcc/JS-Sorting-Algorithm/blob/master/8.countingSort.md

https://zh.wikipedia.org/wiki/%E8%AE%A1%E6%95%B0%E6%8E%92%E5%BA%8F

以上为计数排序算法详细介绍,插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等排序算法各有优缺点,用一张图概括:

关于时间复杂度

平方阶 (O(n2)) 排序 各类简单排序:直接插入、直接选择和冒泡排序。

线性对数阶 (O(nlog2n)) 排序 快速排序、堆排序和归并排序;

O(n1+§)) 排序,§ 是介于 0 和 1 之间的常数。 希尔排序

线性阶 (O(n)) 排序 基数排序,此外还有桶、箱排序。

关于稳定性

稳定的排序算法:冒泡排序、插入排序、归并排序和基数排序。

不是稳定的排序算法:选择排序、快速排序、希尔排序、堆排序。

名词解释:

n:数据规模

k:"桶"的个数

In-place:占用常数内存,不占用额外内存

Out-place:占用额外内存

稳定性:排序后 2 个相等键值的顺序和排序之前它们的顺序相同

文档

如何按照计数进行排序

计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。
推荐度:
为你推荐
资讯专栏
热门视频
相关推荐
描写元宵节的唯美诗词 堆排序怎么排 关于兰花的诗句两句 java快速排序 关于写小动物的诗 描写夏天的诗句简单 踏青诗句最出名诗句 描写燕子的古诗绝句 归并排序python 希尔排序 选择排序法 基数排序怎么排 冒泡排序python 关于放风筝的古诗 桶式排序 计数排序算法c++实现 堆排序法排序怎么排 关于兰花的诗句古诗 快速排序c语言 两句关于动物的诗句 桶排序 写与风筝有关的诗 冒泡排序python代码 基数排序 选择排序 插入排序 java希尔排序算法 归并排序c语言 积累描写燕子的诗句 出门踏青的诗句 5首夏天的古诗简单 描写小动物的古诗 快速排序java 兰花的诗词佳句 元宵节代表诗词 托尔斯泰的名言 列宁的名言 关于乐观的名言 有关友谊的名言 关于交友的名言警句
Top