数据、随机-剑指offer:排序算法实现经验教训总结 -by小雨

废话就不多说了,开始。。。

    言前:写这篇博客要主是加深自己对序排算法的懂得和总结实现算法时的一些验经和训教,如果有误错请指出,谢感

    

    这个是关于算法的维思导图,自己把基于较比的7个算法,写了一个维思导图。维思导图软件应用的是XMind,有免费版感兴趣可以下载。

    本文要主分为两个部份,一个是对于算法的懂得另一个是在算法实现过程当中一些验经和训教的总结。

    一,关于算法

    首先推荐一个子帖http://blog.csdn.net/ctang/article/details/37914 这个是对于算法分析较比好的,在算法实现过程当中要需注意的是快排和归并序排要需应用栈堆或者递归实现。对于快速序排当数据本身有序时会退化到O(N*N)的时间庞杂度中,如果是大数据(我在试测中对于11000以上的有序数据量,就会现出栈堆溢出的常异),因此要需采取非递归,自己应用栈堆较比好。

    二、算法实现中的验经和训教

    最开始时只是用了一个Isort接口,一共7个算法望希用一个类去实现,在实现过程当中,发明这类实现法方太过于庞杂,因为有的算法还要需助辅函数。

    public interface ISort
    {
        void SelectSort();
        void BubbleSort();
        void QuickSort();
        void InsertSort();
        void ShellSort();
        void MergeSort();
        void HeapSort();
    }
后之就计划了另一个接口IAlgorithmSort ,只用一个Sort法方,数参用于示指是正序排还是逆序排 。
    public interface IAlgorithmSort     
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="LittleToBig"> 1....to....n or n....to...1 </param>
        void Sort(bool LittleToBig);
    }
计划一个AlgorithmSort类继承IAlgorithmSort接口,因为它 没有详细实现的序排法方,所以把它定义 为abstract抽象类,不可以实例化。AlgorithmSort要主供给一些序排中要需的共有法方和数据:1按照求要生成数据(逆序,正序,随机)2打印数据3看查数据否是有序4交换数据。详细的序排时由两个抽象法方实现的,见面下代码。
        public void Sort(bool LittleToBig) 
        {
            if (LittleToBig)
                SortPositive();
            else
                SortNegitive();
        }
        public abstract void SortPositive();
        public abstract void SortNegitive();
请注意public abstract void SortPositive();把数据正序排,这个法方是一个虚法方,它的拜访性属是public,当我试尝在子类变改它的拜访符时错出, 请注意无论是abstract还是Virtual 子类都不可以变动它的拜访性属。SortPositive()和SortNegitive()否是该应放在IAlgorithmSort接口中,我也有点豫犹,我试尝放在接口中时,发明对于接口中的法方,如果 不想实现时可以在法方前加 abstract关键字,价值是不可以实例化。

    全部算法实现后就有一个试测问题,为了便利试测AlgorithmSort类中可以生成随机数据,随机正序数据和随机逆序数据,最开始计划的时候是每次停止序排检测时,都调用一下随机函数,然后序排,践实过程当中发明,每次生成随机数据时间消费太大,因此有增加了几个变量,函数初始化时就生成关相的数据。

    _data 是每次序排时要用的数据,_xrData是随机数据,_prData是随机正序数据,_nrData时随机逆序数据,每次序排前_data要需复制关相的数据。

        protected const int LENGTH = 10000;
        private Random _random; 
        protected int [] _data;
        private int[] _xrData;
        private int[] _prData;
        private int[] _nrData;
AlgorithmSort类中还设置了一个CheckPorder函数和CheckNorder函数用来查检序排结果否是符合预期,当然这两个函数放在Test类中较比适合。

    

    这个函数的利益是可以通过颜色通知否是符合预期。

    AlgorithmSort类的源代码

AlgorithmSort类的源代码
    public interface IAlgorithmSort     
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="LittleToBig"> 1....to....n or n....to...1 </param>
        void Sort(bool LittleToBig);
    }
    public abstract class AlgorithmSort : IAlgorithmSort
    {
        protected const int LENGTH = 10000;
        private Random _random; 
        protected int [] _data;
        private int[] _xrData;
        private int[] _prData;
        private int[] _nrData;
        protected AlgorithmSort() 
        {
            _random = new Random();
            _data = new int[LENGTH];
            _xrData = new int[LENGTH];
            _prData=new int[LENGTH];
            _nrData=new int[LENGTH]; 
            newRandomData();
            newRandomPositiveOrderData();
            newRandomNegitiveOrderData();
            //RandomData();
        }
        private void newRandomData() 
        {
            for (int i = 0; i < LENGTH; i++)
            {
                //_data[i] = _random.Next(-2 * LENGTH, 2 * LENGTH);
                _xrData[i] = _random.Next(-2 * LENGTH, 2 * LENGTH); 
            }
        }
        private void newRandomPositiveOrderData() 
        {
            int temp = -LENGTH;
            for (int i = 0; i < LENGTH; i++)
            {
                temp = temp + _random.Next(0, 10);
                _prData[i] = temp;
            }
        }
        private void newRandomNegitiveOrderData() 
        {
            int temp = LENGTH;
            for (int i = 0; i < LENGTH; i++)
            {
                temp = temp + _random.Next(-10, 0);
                //_data[i] = temp;
                _nrData[i] = temp;
            }

        }
        public void RandomData() 
        {
            //for (int i = 0; i < LENGTH; i++)
            //    _data[i] = _random.Next(-2*LENGTH,2*LENGTH);

            for (int i = 0; i < LENGTH; i++) 
            {
                _data[i]=_xrData[i];
            }
        }
        public void RandomPositiveOrderData() 
        {
            //int temp = -LENGTH;
            //for (int i = 0; i < LENGTH; i++)
            //{
            //    temp = temp + _random.Next(0, 10);
            //    _data[i] = temp;
            //}
            for (int i = 0; i < LENGTH; i++)
            {
                _data[i] = _prData[i];
            }
        }
        public void PositiveOrderData() 
        {
            for (int i = 0; i < LENGTH; i++)
            {
                _data[i] = i+1;
            }
        }
        public void NegitiveOrderData()
        {
            for (int i = 0; i < LENGTH; i++)
            {               
                _data[i] =LENGTH-i;
            }
        }
        public void RandomNegitiveOrderData() 
        {
            //int temp = LENGTH;
            //for (int i = 0; i < LENGTH; i++)
            //{
            //    temp = temp + _random.Next(-10, 0);
            //    _data[i] = temp;
            //}
            for (int i = 0; i < LENGTH; i++)
            {
                _data[i] = _nrData[i];
            }
        }
        public void Sort(bool LittleToBig) 
        {
            if (LittleToBig)
                SortPositive();
            else
                SortNegitive();
        }
        public abstract void SortPositive();
        public abstract void SortNegitive();
        public void  Print()
        {
            foreach(int ele in _data)
            {
                Console.WriteLine(ele);
            }
        }
        protected void swap(ref int a,ref int b) 
        {
            int c;
            c = a;
            a = b;
            b = c;
        }
        public void CheckNOrder() 
        {
            bool right=true;
            for (int i = 1; i < LENGTH; i++) 
            {
                if (_data[i - 1] < _data[i]) 
                {
                    right = false;
                    break;
                }
            }
            ConsoleColor currentForeColor = Console.ForegroundColor;
            Console.ForegroundColor = ConsoleColor.Yellow;
            if (right)
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("IS Negitive Order");
            }

            else
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Warning Warning Warning Is NOT Negitive Order");
            }
                
            Console.ForegroundColor = currentForeColor;
        }
        public void CheckPOrder() 
        {
            bool right = true;
            for (int i = 1; i < LENGTH; i++)
            {
                if (_data[i - 1] > _data[i])
                {
                    right = false;
                    break;
                }
            }
            ConsoleColor currentForeColor = Console.ForegroundColor;
            Console.ForegroundColor = ConsoleColor.Yellow;
            if (right)
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("IS Positive Order");
            }

            else
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Warning Warning Warning Is NOT Positive Order");
            }

            Console.ForegroundColor = currentForeColor;
        }
    }
 

    三关于性能试测

    性能试测应用的是老赵供给的一个简略的性能计数器:CodeTimer ,和自己写的一个Test类,要主可以通过AlgorithmSort 作为一个指针,指向子类,可以试测各种各种详细的序排法方的性能。

    函数名命解释:举例Test_N_Random_X ,Test示表是一个试测函数;N示表序排的结果时Negitive即逆序,P代表正序;Random代表应用的数据时随机生成的,X代表随机生成的数据没有次序,P代表随机生成的数据是正序N则代表是随机生成的数据是逆序,Test_N_Random_X的意思是应用随机无序的数据,实现正序排。

    详见代码。

Test源代码
    public class Test
    {
        private AlgorithmSort _testAlg;
        public Test(AlgorithmSort alg)
        {
            _testAlg = alg;
        }
        public void BindAlg(AlgorithmSort alg) 
        {
            if (alg == null)
                return;
            _testAlg = alg;
        }
        public void Test_P_Random_X() 
        {
            _testAlg.RandomData();
            _testAlg.SortPositive();
        }
        public void Test_N_Random_X() 
        {
            _testAlg.RandomData();
            _testAlg.SortNegitive();
        }
        public void Test_P_Random_N() 
        {
            _testAlg.RandomNegitiveOrderData();
            _testAlg.SortPositive();
        }
        public void Test_N_Random_P() 
        {
            _testAlg.RandomPositiveOrderData();
            _testAlg.SortNegitive();
        }
        public void Pack_Test(string algName) 
        {
            string testStr = "试测{0}";
            testStr = string.Format(testStr,algName);
            CodeTimer.Time(testStr+"随机逆序排", 1, Test_N_Random_X);
            CodeTimer.Time(testStr + "随机正序排", 1, Test_P_Random_X);
            CodeTimer.Time(testStr + "正序逆排", 1, Test_N_Random_P);
            CodeTimer.Time(testStr + "逆序正排", 1, Test_P_Random_N);
        }
        public void Pack_OutTest(string algName)
        {
            string testStr = "试测{0}";
            testStr = string.Format(testStr, algName);
            CodeTimer.Time(testStr + "随机逆序排", 1, Test_N_Random_X);
            _testAlg.CheckNOrder();
            CodeTimer.Time(testStr + "随机正序排", 1, Test_P_Random_X);
            _testAlg.CheckPOrder();
            CodeTimer.Time(testStr + "正序逆排", 1, Test_N_Random_P);
            _testAlg.CheckNOrder();
            CodeTimer.Time(testStr + "逆序正排", 1, Test_P_Random_N);
            _testAlg.CheckPOrder();
        }
    }
下图是部份试测效果图

    

    部全代码下载 http://files.cnblogs.com/CaiBaoZi/Sort.rar

 

文章结束给大家分享下程序员的一些笑话语录: 人脑与电脑的相同点和不同点,人脑会记忆数字,电脑也会记忆数字;人脑会记忆程序,电脑也会记忆程序,但是人脑具有感知能力,这种能力电脑无法模仿,人的记忆会影响到人做任何事情,但是电脑只有程序软件。比尔还表示,人脑与电脑之间最重要的一个差别就是潜意识。对于人脑存储记忆的特别之处,比尔表示,人脑并不大,但是人脑重要的功能是联络,人脑会把同样的记忆存储在不同的地方,因此记忆读取的速度就不相同,而这种速度取决于使用的频率和知识的重要性。人脑的记忆存储能力会随着年龄增长而退化,同时记忆的质量也会随着年龄退化。经典语录网


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值