基数排序

来源:互联网 发布:网络用语dm是什么意思 编辑:程序博客网 时间:2024/06/05 18:02

C#基数排序

今天小智给大家带来的是c#中的基数排序。

基数排序,与选择,冒泡,插入排序不同的是,前者都属于【比较性】排序,而基数排序是【分配式】排序。

就是透过数据的部分资讯,将待排序的元素分配至某些【桶】中,从而达到排序的作用,他属于稳定性的排序。

基数排序的方式有两种:MSD或LSD,MSD是从数据的高位(左边)开始,而LSD是从数据的低位(右边)开始。

下来让小智根据代码给大家详细介绍下吧:(LSD方式)

static void Main(string[] args)        {            int []data =new int [10]{1117, 222, 938, 194, 550, 140, 280, 650, 390, 81};            int[,] temp = new int[10, 10];            int[] order = new int[10];            int i, j, k, n=1, lsd;            Console.WriteLine("原数据:");            foreach( int number in data)                Console.Write("{0} ",number);            Console.WriteLine();            Console.WriteLine("基数排序——桶排:");            while (n <= 1000)           //1000:10的3(所给最大数据的位数-1)次方            {                k = 0;                for (i = 0; i < 10; i++)            //将数组data的数按规律(个十百)放进桶temp内                {                    lsd = (data[i] / n) % 10;                   //循环时lsd的变化为个,十,百。                    temp[lsd, order[lsd]] = data[i];                    order[lsd]++;                }                for (i = 0; i < 10; i++)                            {                    if (order[i] != 0)                    {                        for (j = 0; j < order[i]; j++)      //将temp桶内的数据转入data数组内                        {                            data[k] = temp[i, j];                            //Console.Write("{0} ", data[k]);                            k++;                        }                    }                    order[i] = 0;                }                //Console.WriteLine();                n *= 10;            }            Console.WriteLine("排序后:");            foreach(int number in data )                Console.Write("{0} ",number);            Console.WriteLine();            Console.ReadKey();        }

这是C#下的基数排序,待排序的元素为

1117, 222, 938, 194, 550, 140, 280, 650, 390, 81
(1).先根据他们个位数的数值将它们分配至编号0-9的桶子中

for (i = 0; i < 10; i++)            //将数组data的数按规律(个十百)放进桶temp内                {                    lsd = (data[i] / n) % 10;                   //循环时lsd的变化为个,十,百。                    temp[lsd, order[lsd]] = data[i];                    order[lsd]++;                }

0       1   2    3    4 5 6 789

550 81222194            1117      938

140

280

650

390

(2).放入桶子后在按顺序将各个元素放回data数组内,此时data数组数据为{550,140,280,650,390,81,222,194,1117,938};

 for (i = 0; i < 10; i++)                            {                    if (order[i] != 0)                    {                        for (j = 0; j < order[i]; j++)      //将temp桶内的数据转入data数组内                        {                            data[k] = temp[i, j];                            //Console.Write("{0} ", data[k]);                            k++;                        }                    }                    order[i] = 0;                }

(3)再循环进行(1)(2)步,直到n<=1000

那么这个跳出循环条件n<=1000怎么判断呢,这个1000其实是10的3(待排序元素中最大元素的位数-1)次方。

下面小智给大家把基数排序的后几步数据展示一下 :

a.第二次循环(以十位为基准放入桶内)

0    1   2   3   4   5   6   7  8  9

1117222938140 550280 390

65081194

b.第三次循环(以百位为基准放入桶内)

0 1 2 3 456 7 8 9

81 1117222390550 650938

140280

194

c.第四次循环(以千位为基准放入桶内)

0 1 2 3 456 7 8 9

81      1117

140

194

222

280

390

550

650

938

相信大家也看见了到最后一次循环大部分数占据了0列的空间,而右边偌大的空间都没有用,但是他仍然在,所以这就是基数排序的一个弊端,

他不适合对位数多的数据(10000)或者总量多的数据的排序,否则会极大地浪费空间与时间,比如说排序{2,5,3,9,4,10000000},如果要排序这个数组,基数排序就要运行8次那种大循环,分配6*6个int字节的内存空间,而其他的排序则很快就完了,也不会浪费多少内存。

这就是整个基数排序的思想,不知道亲们懂了吗!!再会


0 0
原创粉丝点击