算法--中位数计算

中位数(Median)

 1、定义:一组数据按从小到大(或从大到小)的顺序依次排列,处在中间位置的一个数(或最中间两个数据的平均数,注意:和众数不同,中位数不一定在这组数据中)。 

注:当个数为基数时,取最中间位置的数;当个数为偶数时,取最中间两个数的平均数。

 2、从小到大排序,可以先用冒泡排序,然后取中位数,那么先看下冒泡排序算法,代码如下:

        public static void BubbleSort(this IList<double> array)
        {
            if (array == null || array.Count == 0)
            {
                return;
            }

            int count = array.Count;

            for (int i = 0; i < count - 1; i++)
            {
                for (int j = 0; j < count - i - 1; j++)
                {
                    if (array[j + 1] < array[j])
                    {
                        double temp = array[j + 1];
                        array[j + 1] = array[j];
                        array[j] = temp;
                    }
                }
            }
        }

        public static void BubbleSort<T>(this IList<T> array) where T : IComparable
        {
            if (array == null || array.Count == 0)
            {
                return;
            }

            int count = array.Count;

            for (int i = 0; i < count - 1; i++)
            {
                for (int j = 0; j < count - i - 1; j++)
                {
                    if (array[j + 1].CompareTo(array[j]) < 0)
                    {
                        T temp = array[j + 1];
                        array[j + 1] = array[j];
                        array[j] = temp;
                    }
                }
            }
        }

 一种为基本的算法,另外一种为泛型的。排序后取中位数即可。

3、但是我们并不需要全部从小到大排序,只需要一部分排序即可(即在冒泡的基础上改进),先看代码:

        public static double Median(this IList<double> array)
        {
            if (array == null)
            {
                throw new ArgumentNullException("array");
            }

            return array.ToArray().Median();
        }

        public static double Median(this double[] array)
        {
            if (array == null)
            {
                throw new ArgumentNullException("array");
            }

            int endIndex = array.Length / 2;

            for (int i = 0; i <= endIndex; i++)
            {
                for (int j = 0; j < array.Length - i - 1; j++)
                {
                    if (array[j + 1] < array[j])
                    {
                        double temp = array[j + 1];
                        array[j + 1] = array[j];
                        array[j] = temp;
                    }
                }
            }

            if (array.Length % 2 != 0)
            {
                return array[endIndex];
            }

            return (array[endIndex - 1] + array[endIndex]) / 2;
        }

        public static decimal Median(this IList<decimal> array)
        {
            if (array == null)
            {
                throw new ArgumentNullException("array");
            }

            return array.ToArray().Median();
        }

        public static decimal Median(this decimal[] array)
        {
            if (array == null)
            {
                throw new ArgumentNullException("array");
            }

            int endIndex = array.Length / 2;

            for (int i = 0; i <= endIndex; i++)
            {
                for (int j = 0; j < array.Length - i - 1; j++)
                {
                    if (array[j + 1] < array[j])
                    {
                        decimal temp = array[j + 1];
                        array[j + 1] = array[j];
                        array[j] = temp;
                    }
                }
            }

            if (array.Length % 2 != 0)
            {
                return array[endIndex];
            }

            return (array[endIndex - 1] + array[endIndex]) / 2;
        }

 改进的代码只有2行

            int endIndex = array.Length / 2;

            for (int i = 0; i <= endIndex; i++)

计算一半即可。个人还是喜欢用decimal来进行计算,误差较小,虽然执行速度较其他基础类型慢一点。

4、操作方式如下:

            double[] array = { 47,5,6,-88,6,1,-7,-17,-232};
            double result = array.Median();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值