排序七:基数排序

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading.Tasks;
  6
  7 namespace RadixSort
  8 {
  9     class Program
 10     {
 11         static void Main(string[] args)
 12         {
 13             int[] arr = new int[10];
 14             Random rd = new Random();
 15             for (int i = 0; i < arr.Length; i++)
 16             {
 17                 arr[i] = rd.Next(10000);
 18             }
 19             RadixSort(arr, 4);
 20         }
 21         //基数排序-最低位优先法【LSD(Least significant digital)】
 22         public static void RadixSort(int[] arr, int numberMaxLength)
 23         {
 24             //存放每次排序后的元素
 25             List<int> list = new List<int>();
 26             //十个桶
 27             List<int>[] listArr = new List<int>[10];
 28             //存放当前元素
 29             string currentItem;
 30             //存放当前元素中的字符
 31             char currentChar;
 32             //给十个桶分配内存初始化
 33             for (int i = 0; i < listArr.Length; i++)
 34             {
 35                 listArr[i] = new List<int>();
 36             }
 37             //一共执行numberMaxLength次,numberMaxLength是元素的最大位数
 38             for (int i = 0; i < numberMaxLength; i++)
 39             {
 40                 foreach (int number in arr)
 41                 {
 42                     //当前元素转成字符串
 43                     currentItem = number.ToString();
 44                     try
 45                     {
 46                         //从个位向高位开始分桶
 47                         currentChar = currentItem[currentItem.Length - i - 1];
 48                     }
 49                     catch
 50                     {
 51                         //如果发生异常,则将该数压入listArr[0]。比如说5是没有十位数的,
 52                         //执行上面的操作肯定会发生越界异常的,这正是期望的行为,我们认为5的十位数是0,
 53                         //所以将它压入listArr[0]的桶里。
 54                         listArr[0].Add(number);
 55                         continue;
 56                     }
 57                     switch (currentChar)
 58                     {
 59                         case ‘0‘:
 60                             listArr[0].Add(number);
 61                             break;
 62                         case ‘1‘:
 63                             listArr[1].Add(number);
 64                             break;
 65                         case ‘2‘:
 66                             listArr[2].Add(number);
 67                             break;
 68                         case ‘3‘:
 69                             listArr[3].Add(number);
 70                             break;
 71                         case ‘4‘:
 72                             listArr[4].Add(number);
 73                             break;
 74                         case ‘5‘:
 75                             listArr[5].Add(number);
 76                             break;
 77                         case ‘6‘:
 78                             listArr[6].Add(number);
 79                             break;
 80                         case ‘7‘:
 81                             listArr[7].Add(number);
 82                             break;
 83                         case ‘8‘:
 84                             listArr[8].Add(number);
 85                             break;
 86                         case ‘9‘:
 87                             listArr[9].Add(number);
 88                             break;
 89                         default:
 90                             throw new Exception("unknow error");
 91                     }
 92                 }
 93                 //清空list
 94                 list.Clear();
 95                 //将十个桶里的数据重新排列,压入list
 96                 for (int j = 0; j < listArr.Length; j++)
 97                 {
 98                     foreach (int number in listArr[j].ToArray<int>())
 99                     {
100                         list.Add(number);
101                         //清空每个桶
102                         listArr[j].Clear();
103                     }
104                 }
105                 //arr指向重新排列的元素
106                 arr = list.ToArray<int>();
107             }
108             foreach (int i in list)
109             {
110                 Console.WriteLine(i);
111             }
112         }
113     }
114 }
时间: 2024-07-31 01:28:17

排序七:基数排序的相关文章

排序算法(七)非比较排序:计数排序、基数排序、桶排序

前面讲的是比较排序算法,主要有冒泡排序,选择排序,插入排序,归并排序,堆排序,快速排序等. 非比较排序算法:计数排序,基数排序,桶排序.在一定条件下,它们的时间复杂度可以达到O(n). 一,计数排序(Counting Sort) (1)算法简介 计数排序(Counting sort)是一种稳定的排序算法.计数排序使用一个额外的数组C,其中第i个元素是待排序数组A中值等于i的元素的个数.然后根据数组C来将A中的元素排到正确的位置.它只能对整数进行排序. (2)算法描述和实现 得到待排序数的范围(在

常见的五类排序算法图解和实现(多关键字排序:基数排序以及各个排序算法的总结)

基数排序思想 完全不同于以前的排序算法,可以说,基数排序也叫做多关键字排序,基数排序是一种借助“多关键字排序”的思想来实现“单关键字排序”的内部排序算法. 两种方式: 1.最高位优先,先按照最高位排成若干子序列,再对子序列按照次高位排序 2.最低位优先:不必分子序列,每次排序全体元素都参与,不比较,而是通过分配+收集的方式. 多关键字排序 例:将下表所示的学生成绩单按数学成绩的等级由高到低排序,数学成绩相同的学生再按英语成绩的高低等级排序.        第一个关键字是数学成绩,第二个关键字是英

排序八 基数排序

要点 基数排序又称桶排序. 基数排序与本系列前面讲解的七种排序方法都不同,它不需要比较关键字的大小. 它是根据关键字中各位的值,通过对排序的N个元素进行若干趟“分配”与“收集”来实现排序的. 不妨通过一个具体的实例来展示一下,基数排序是如何进行的. 设有一个初始序列为: R {50, 123, 543, 187, 49, 30, 0, 2, 11, 100}. 我们知道,任何一个阿拉伯数,它的各个位数上的基数都是以0~9来表示的. 所以我们不妨把0~9视为10个桶. 我们先根据序列的个位数的数字

【数据结构】非比较排序算法(实现计数排序和基数排序)

● 计数排序 1.算法思想: 计数排序是直接定址法的变形.通过开辟一定大小的空间,统计相同数据出现的次数,然后回写到原序列中. 2.步骤: 1)找到序列中的最大和最小数据,确定开辟的空间大小. 2)开辟空间,利用开辟的空间存放各数据的个数. 3)将排好序的序列回写到原序列中. 具体实现如下: void CountSort(int *arr, int size) {  assert(arr);  int min = arr[0];  int max = arr[0];  int num = 0;

有Leetcode中一道题,谈桶排序,基数排序和计数排序

几种非比较排序 在LeetCode中有个题目叫Maximum Gap,是求一个非排序的正数数列中按顺序排列后的最大间隔.这个题用桶排序和基数排序都可以实现.下面说一下桶排序.基数排序和计数排序这三种非比较排序. 桶排序 这种排序的主要思想是,把数列分配到多个桶中,然后再在各个桶中使用排序算法进行排序,当然也可以继续使用桶排序. 假设数组的最大值是A,最小值是B,长度是L,则每个桶的大小可以是S=Max(1,(A-B)/(L-1))则可以分为(A-B)/S+1个桶. 对于数列中的数字x,用(x-B

桶式排序和基数排序

之前总结了基于比较模型的常见排序算法,它们中最快的也要消耗O(nlogn)时间.但是我们应该知道的是,在一定条件下以线性时间进行排序依然是可能的.桶式排序和基数排序在合适的条件下就是以线性时间执行的算法. 桶式排序(bucket sort): 思想:如果我们限制需要排序的整数的范围,比如说我们有n个整数,范围从0到m-1,我们可以利用这个信息得到一种快速的排序算法.我们留置一个数组,称之为t,大小为m,并初始化为0.于是t有m个单元(桶),开始时它们都是空的.当i被读入时t[i]加一.在所有的输

SDUT 3404 数据结构实验之排序七:选课名单.!?

数据结构实验之排序七:选课名单 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 随着学校规模的扩大,学生人数急剧增加,选课名单的输出也成为一个繁重的任务,我校目前有在校生3万多名,两千多门课程,请根据给定的学生选课清单输出每门课的选课学生名单. Input 输入第一行给出两个正整数N( N ≤ 35000)和M(M ≤ 2000),其中N是全校学生总数,M是课程总数,随后给出N行,每行包括

算法——排序之基数排序

基数排序也是稳定的内排序. 因为它的实现是基于内部使用了稳定的排序实现的所以基数排序整体是稳定的,而且时间复杂度为O(n). 举个例子: 现在我们将一些3(多)位数排序,如果你说直接判断就好的话,那你就太天真了,因为那就又变成看O(nlgn)或者O(n2). 如何能降低时间复杂度变成O(n) 呢? 那就要使用线性时间的排序了,正如上篇的计数排序. 基数排序 利用的是计数排序进行排序的.因为计数排序是稳定的排序,即排序后的大小顺序 会与 上一轮的排序顺序结果一致. 再举个例子: 排序前 第一遍排序

桶排序和基数排序

桶排序的基本思想 假设有一组长度为N的待排关键字序列K[1....n].首先将这个序列划分成M个的子区间(桶) .然后基于某种映射函数 ,将待排序列的关键字k映射到第i个桶中(即桶数组B的下标 i) ,那么该关键字k就作为B[i]中的元素(每个桶B[i]都是一组大小为N/M的序列).接着对每个桶B[i]中的所有元素进行比较排序(可以使用快排).然后依次枚举输出B[0]....B[M]中的全部内容即是一个有序序列. 假如待排序列K= {49. 38 . 35. 97 . 76. 73 . 27.

计数排序、基数排序与桶排序

一.计数排序 稳定. 当输入的元素是n 个小区间(0到k)内整数时,它的运行时间是 O(n + k),空间复杂度是O(n). const int K = 100; //计数排序:假设输入数据都属于一个小区间内的整数,可用于解决如年龄排序类的问题 //Input:A[0, ..., n-1], 0 <= A[i] < K //Output:B[0, ..., n-1], sorting of A //Aux storage C[0, ..., K) void CountSort(int A[],