C#非比较排序(计数排序+基数排序)

非比较排序(计数排序+基数排序)C#

非比较排序:根据数据状况来排序(应用不是很广,数据状况太差不建议使用)
1、计数排序
例:一组员工他们的年龄为int类型的数组(已知员工年龄范围0~150),要求给他们的年龄进行排序。
思路:
额外申请空间int[] arr=new int[151];
将arr数组的序号作为年龄,序号对应的数字来存储该年龄的人数
遍历原数组
如果第一个人为20岁,则arr[20]=1;
第二个人为23岁,则arr[23]=1;
第三个人为20岁,则arr[20]=2;

时间复杂度O(N) 空间换时间
代码实现:

public void Jishu(int[] age)
{
    
    
    int[] arr = new int[151];
    for (int i = 0; i < age.Length; i++)
    {
    
    
        arr[age[i]]++;
    }

    for (int j = 0; j < arr.Length; j++)
    {
    
    
        if (arr[j] != 0)
        {
    
    
            Console.WriteLine(j+"岁的人数为"+arr[j]);
        }
    }
}

2、基数排序(优于计数排序)
使用条件:要排的数据要有进制(十进制,二进制等等)
例对一个十进制数组进行排序
int[] arr=new int[]{17,13,25,100,72};
思路
(1)先看最大数有几位,把其他不到位数的数字前面补0
数组最大位数为3,所以其他不到三位的补零{017,013,025,100,072}
(2)准备10个容器——桶(数组中数为十进制,数据为几进制就准备几个桶)
“容器”=>可以是数组、队列、栈…
【例子中可以认为是队列】
(3)
先根据个位数,017,个位数为7,就放到7号桶;013,放到3号桶;025,放到5号桶;100,放到0号桶;072,放到2号桶;
然后从左往右依次把桶中的数倒出来,即100,072,013,025,017
再根据十位数来决定进几号桶,100,十位数为0,进零号桶;072,进7号桶;013.进1号桶…
然后在从左往右倒出,100,013,017,025,072
然后按百位进桶,100,百位为1,进1号桶;013,百位为0,进0号桶;017,进零号桶…
然后在从左往右倒出,013,017,025,072,100;排序完成
在这里插入图片描述
代码思路:
1、先取个位,制作词频表
即取出每个数的个位数,定义一个数组名为count,将数组序号作为个位数数值,序号对应数组存储<=该序号的数的个数
在这里插入图片描述
2、从右向左遍历数组(符合桶的先进先出),开一个数组bucket[10],代表桶
(1) 072,个位数为2,即<=2;词频表内<=2对应的个数为2,即有2个,所以将072放到bucket[2-1]中,2-1中的2对应的是个数2。count[2]–,这个2代表个位数是2.
(2)100,个位数为0,即<=0;词频表内<=0对应的个数为1,即有1个,所以将100放到bucket[1-1]中。count[0]–
(3)025,个位数为5,即<=5;词频表内<=5对应的个数为4,即有4个,所以将025放到bucket[4-1]中。count[4]–

代码实现:

public void BaseSorts(int[] arr)
{
    
    
    int digit = FindMaxDigits(arr);//找到最大值有几位
    double index = 1.0;//用来记录取第几位
    int digitWhat;//记录位数的数值
    for (int i = 0; i < digit; i++)//有几位就进行几次进桶出桶
    {
    
    
        //制作词频表
        int[] count = new int[10];//定义词频表
        for (int j = 0; j < arr.Length; j++)
        {
    
    
            digitWhat = arr[j] % (int)(Math.Pow(10f, index)) / (int)(Math.Pow(10f, index - 1));
            for (int k = digitWhat; k < 10; k++)
            {
    
    
                count[k]++;
            }
        }
        
        //进行进出桶操作
        int[] bucket = new int[10];
        for (int buc = arr.Length-1; buc >=0; buc--)//从右向左遍历
        {
    
    
            int digitW = arr[buc] % (int)(Math.Pow(10f, index)) / (int)(Math.Pow(10f, index - 1));
            bucket[count[digitW] - 1] = arr[buc];
            count[digitW]--;
        }
       Array.Copy(bucket,arr,arr.Length);
       index++;
    }
}

public int FindMaxDigits(int[] arr)
{
    
    
    int digit = 0;
    int max = arr[0];
    for (int i = 1; i < arr.Length; i++)
    {
    
    
        max = max > arr[i] ? max : arr[i];
    }

    while (max != 0)
    {
    
    
        max = max / 10;
        digit++;
    }
    return digit;
}

如有问题,欢迎留言ㄟ(≧◇≦)ㄏ

猜你喜欢

转载自blog.csdn.net/weixin_51565051/article/details/130691096