算法手记附1 随机化输入与计时器

1.随机化输入

在快速排序算法的使用中,发现其性能是不稳定的,它的速度取决于输入情况,最好的情况下复杂度为O(NlogN),最坏情况下为O(N^2).

最简单的优化方法是随机化输入,打乱输入数组顺序,这样可以将不良输入带来低劣性能的可能性降到最低,对于预测算法的运行时间是十分重要的。

考虑到,在c++中std标准库已有random_shuffle函数,其他语言也有类似方法,但c#并没有此标准函数,这样我索性自己实现一个。

设计:

这里按照最简单的O(N)来设计,需要N次交换,实现起来无疑很简单。

实现:

public class RandomShuffle
    {
        private static Random rd;
        private static int N;
        public static IComparable[] shuffle(IComparable[] a)
        {
            rd = new Random();
            N = a.Length;
            for (var i = 0; i < N; i++)
            {
                var newPosition = rd.Next(N);
                var temp = a[i];
                a[i] = a[newPosition];
                a[newPosition] = temp;
            }
            return a;
        }
}

总结:

这里使用迭代写起来会更简洁明了,但是大规模的迭代会导致线程栈StackoverflowException,所以使用循环会更安全。

2.计时器

衡量一个算法的性能主要有两个方面:运行时间与内存性能。算法分析中,运行时长是一个很重要的衡量指标,但准确测量给定程序的运行时长时间很困难的事情,不过幸运地是我们只需要近似的结果就可以了。

我们可以使用系统API来实现一个精度尚可的计时器,可以帮助我们验证算法的速度。

设计:

设计一个Stopwatch类,它的elapsedTime()方法能够输出程序执行时间。它的实现基于.NET框架的DateTime类,能返回以毫秒/秒计数的结果。

实现:

 public class Stopwatch
    {
        private static DateTime startTime;
        public Stopwatch(DateTime time)
        {
            startTime = time;
        }
        public void elapsedTime()
        {
            DateTime endTime = DateTime.Now;
            double time = (endTime.Hour - startTime.Hour) * 3600 * 1000 + (endTime.Minute - startTime.Minute) * 60 * 1000
                          + (endTime.Second - startTime.Second) * 1000 + (endTime.Millisecond - startTime.Millisecond);
            if (time > 1000)
            {
                time /= 1000;
                Console.WriteLine("time: " + time + "s");
            }
            else
                Console.WriteLine("time: " + time + "ms");
        }
    }

总结:

这样的计时器虽然精度不高,但是足以用来简单地评估算法的性能了。

时间: 2024-08-06 11:10:37

算法手记附1 随机化输入与计时器的相关文章

排序算法之快速排序的随机化版本

4.3 快速排序的随机化版本 这种方法并不是一种全新的排序算法,而是在快速排序的基础上加入随机化的因素,因素,因而仍然将其作为第四种方法(快速排序)的一种补充. 为什么要提出快速排序的随机化版本,主要是对于快速排序法其划分情况的好坏会直接影响排序的效率,而且,快速排序的平均性能较好,所以,加入随机化成分,可以使该算法对于所有输入均能获得较好的平均情况性能. 针对加入随机化的环节,选取的是选取主元的环节,因为主元的选取直接影响快速排序算法的数组划分. C代码实现为: #include <stdio

算法手记(4)算法分析

“我的程序会运行多长时间?为什么我的程序耗尽了所有内存?” 在我们使用计算机解决困难问题或是处理大量数据时,不可避免地会产生这些疑问.为这些基础问题给出答案有时其实非常简单,这个过程是科学方法,这就是我们今天讨论的内容. 科学方法概述: 科学家用于观察世界的方法对于研究计算机程序一样有效: 1.观察真实世界特点 2.提出假设模型 3.根据假设模型预测未来事件 4.继续观察并核实预测的准确性 5.如此反复直至确认预测与观察一致 正如爱因斯坦所说:“再多的实验也不一定能够证明我是对的,但只需要一个实

swift算法手记-10

http://blog.csdn.net/myhaspl private func findnode(val:Int)->Bool{//http://blog.csdn.net/myhaspl //查找结点http://blog.csdn.net/myhaspl if let mysltop = slinktop{ var mynode:skipLinkNode=mysltop while true{ while true{ if let nextnd = mynode.nextnode { l

优化IPOL网站中基于DCT(离散余弦变换)的图像去噪算法(附源代码)。

在您阅读本文前,先需要告诉你的是:即使是本文优化过的算法,DCT去噪的计算量依旧很大,请不要向这个算法提出实时运行的苛刻要求. 言归正传,在IPOL网站中有一篇基于DCT的图像去噪文章,具体的链接地址是:http://www.ipol.im/pub/art/2011/ys-dct/,IPOL网站的最大特点就是他的文章全部提供源代码,而且可以基于网页运行相关算法,得到结果.不过其里面的代码本身是重实现论文的过程,基本不考虑速度的优化,因此,都相当的慢. 这篇文章的原理也是非常简单的,整个过程就是进

hdu 1317 XYZZY 国产SPFA算法AC,,题目输入部分真特么难懂。。内有解析

XYZZY Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3017    Accepted Submission(s): 824 Problem Description It has recently been discovered how to run open-source software on the Y-Crate gami

算法手记(5)初级排序算法

排序是将一组对象按照一定的规则重新排列的过程.即使目前完全可以使用标准库中的排序函数,学习排序算法仍然有着较大意义:   排序算法的学习可以帮助你全面了解比较算法性能的方法: 类似的技术上能有效解决其他类型的问题: 排序算法通常是我们解决问题的第一步: 更重要的是这些算法都很经典,优雅和高效. 排序在商业数据处理分析和现代科学中占有重要的地位,其中快速排序算法被誉为20世纪科学和工程领域十大算法之一.今天我们要看的就是相对简单但很经典的初级排序算法,包括选择排序,插入排序及Shell排序. 准备

七大查找算法(附C语言代码实现)

来自:Poll的笔记 - 博客园 链接:http://www.cnblogs.com/maybe2030/p/4715035.html 阅读目录 1.顺序查找 2.二分查找 3.插值查找 4.斐波那契查找 5.树表查找 6.分块查找 7.哈希查找 查找是在大量的信息中寻找一个特定的信息元素,在计算机应用中,查找是常用的基本运算,例如编译程序中符号表的查找.本文简单概括性的介绍了常见的七种查找算法,说是七种,其实二分查找.插值查找以及斐波那契查找都可以归为一类--插值查找.插值查找和斐波那契查找是

算法手记(7)快速排序

终于到了经典的快排了,作为20世纪科学和工程领域十大算法之一,自60年代发明以来,一直吸引着一批批工程师和科学家对其改进,今天我们就分析快排算法以及它的几种改进方案. 快速排序 概述:快速排序算法也是基于分治思想的方案,与归并排序不同的是,它是原地排序,同时可以将长度为N的数组排序所需的时间和NlogN成正比,我们已经学习过的算法都无法将这两个优点结合起来. 快速排序流行的原因是因为它实现简单,适用于各种不同的输入数据且在一般应用中比其他算法要快得多,他可能是使用最广泛的算法了. 分析: 快排是

算法手记(2)Dijkstra双栈算术表达式求值算法

这两天看到的内容是关于栈和队列,在栈的模块发现了Dijkstra双栈算术表达式求值算法,可以用来实现计算器类型的app. 编程语言系统一般都内置了对算术表达式的处理,但是他们是如何在内部实现的呢?为了了解这个过程,我们可以自行搭建一套简易的算术表达式处理机制,这里就用到栈特性和本篇提到的Dijkstra算法. 概述:     算术表达式可能是一个数.或者是由一个左括号.一个算术表达式.一个运算符.另一个算术表达式和一个右括号组成的表达式.为了简化问题,这里定义的是未省略括号的算术表达式,它明确地