zoukankan      html  css  js  c++  java
  • 算法图解读书笔记

    二分法查找

    • 对于区间[a,b]上连续不断且f(a)·f(b)<0的函数y=f(x),通过不断地把函数f(x)的零点所在的区间一分为二,使区间的两个端点逐步逼近零点。

    • 适用于提高大列表查询速度,对于包含n个元素的列表,时间复杂度为:O(log2n)。

    • 列表必须有序,并且当列表中存在多个相同元素时并非返回列表中第一次出现元素,不同实现算法获取到元素索引也不一定相同。

    • 代码实现1

        /// <summary>
        /// 递归实现元素查找
        /// <para>集合长度不变,左右查找边界移动。</para>
        /// <para>已经做集合有序性检查,必须升序,否则返回-1</para>
        /// <para>集合中存在查找元素时返回索引,否则返回-1。</para>
        /// </summary>
        /// <param name="list">查找集合</param>
        /// <param name="t">待查找元素</param>
        /// <param name="left">查找左边界</param>
        /// <param name="right">查找右边界</param>
        /// <returns></returns>
        static int FindIndexByBisection(List<int> list, int t, int left, int right)
        {
            /*保证集合有序*/
            if (list[left] > list[right])
                return -1;
      
            /*集合中存在的元素一定在最小值与最大值之间*/
            if (t < list[left] || t > list[right])
                return -1;
      
            /*左右边界已经首次靠近,但是两边界所在元素均不等于待查找元素,直接返回*/
            if (right - left == 1 && list[left] != t && list[right] != t)
                return -1;
      
            int midIndex = (left + right) / 2;
            int midValue = list[midIndex];
      
            if (t < midValue)
                return FindIndexByBisection(list, t, left, midIndex);
            else if (t > midValue)
                return FindIndexByBisection(list, t, midIndex, right);
            else
                return midIndex;
        }
      
    • 代码实现2

        /// <summary>
        /// 递归实现元素查找
        /// <para>集合长度变化,左右查找边界固定。</para>
        /// <para>已经做集合有序性检查,必须升序,否则返回-1。</para>
        /// <para>集合中存在查找元素时返回索引,否则返回-1。</para>
        /// </summary>
        /// <param name="list">查找集合</param>
        /// <param name="t">待查找元素</param>
        /// <param name="index">待查找元素索引</param>
        static void FindIndexByBisection(List<int> list, int t, ref int index)
        {
            /*初始值处理,防止调用方法中设置了错误默认值*/
      
            int count = list.Count;
            int midIndex = count / 2;
            int midValue = list[midIndex];
      
            /*找到元素立即返回*/
            if (t == midValue)
            {
                index += 1;
                return;
            }
      
            /*未找到元素,且集合长度变为1返回-1*/
            if (list.Count == 1)
            {
                index = -1;
                return;
            }
      
            /*未找到元素,集合长度大于1,但集合无序返回-1*/
            if (list[count - 2] > list[count - 1])
            {
                index = -1;
                return;
            }
      
            List<int> midList = list.Take(midIndex).ToList();
            if (t > midValue)
            {
                index += midIndex;//元素比集合中间位置元素大时将中间元素索引累加上去
                midList = list.Skip(midIndex).ToList();
            }
            FindIndexByBisection(midList, t, ref index);
        }
      

    算法效率

    • 大O表示法表示最糟糕情况下程序的运行时间。
    • 常见大O运行时间
      • O(log n) 对数时间,二分查找。
      • O(n) 线性时间,简单查找。
      • O(n * log n) 快速排序算法。
      • O(n*n) 选择排序算法。
      • O(n!) 旅行商问题。
    • 算法的速度指的并非时间,而是操作数的增速。
    • 谈论算法的速度时,我们说的是随着输入的增加,其运行时间将以什么样的速度增加。
    • 大O表示法忽略常量是由于不同算法间效率相差几个数量级,而对于效率相近的算法常量有时候事关重大。

    选择排序

    • 第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。

    • 时间复杂度O(n*n)。

    • 代码实现1

        /// <summary>
        /// 选择排序
        /// <para>时间复杂度o(n^2)</para>
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        static List<int> SelectionSort(List<int> list)
        {
            var result = new List<int>();
      
            for (var i = 0; i < list.Count; i++)
            {
                var minValue = list[i];
                for (var j = i; j < list.Count; j++)
                {
                    if (list[j] < minValue)
                        minValue = list[j];
                }
                result.Add(minValue);
            }
            return result;
        }
      

    递归

    • 原则 如果使用循环,代码的性能可能更高;如果使用递归,程序可能更容易理解。如何选择要看什么对你来说更重要。
    • 组成
      • 基线条件指什么条件下结束函数自我调用,避免无限循环;
      • 递归条件指函数调用自己。

    快速排序

    • 分而治之策略

      • 找出基线条件,条件尽可能简单。
      • 不断将问题分解,直到符合基线条件。
    • 快速排序原理

      • 从数组中随机地选择一个元素作为基准值;
      • 找出比基准值小以及比基准值大的元素,将数组分区;
        • 小于基准值的元素构成的子数组;
        • 基准值;
        • 大于基准值的元素构成的子数组。
      • 对两个子数组进行快速排序。
    • 时间复杂度O(n log n)。

    • 代码实现1

        /// <summary>
        /// 快速排序
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        static List<int> QuickSort(List<int> list)
        {
            /*基准条件:当列表为空或者只存在一个元素时一定有序,返回列表*/
            if (list?.Count <= 1)
                return list;
      
            var midIndex = list.Count / 2;
            var midValue = list[midIndex];//基准值
            var lessList = new List<int>();//左列表
            var greaterList = new List<int>();//右列表
            for (int i = 1; i < list.Count; i++)
            {
                if (list[i] <= midValue)
                    lessList.Add(list[i]);
                else
                    greaterList.Add(list[i]);
            }
      
            lessList = QuickSort(lessList);
            greaterList = QuickSort(greaterList);
      
            var result = new List<int>();
            result.AddRange(lessList);
            result.Add(midValue);
            result.AddRange(greaterList);
            return result;
        }
      

    散列表

    • 散列函数
      • 总是将相同的输入映射到相同的索引;
      • 将不同的输入映射到不同的索引;
      • 知道数组大小,只返回有效索引。
    • 填装因子散列表包含的元素数/位置总数。
    • 冲突
      • 场景给两个键分配的位置相同。
      • 性能
        • 数组中冲突位置存放一个链表,而将冲突键存到链表中。可以避免冲突性能较低。
        • 保证较低的填装因子(<=1)。
    • 时间复杂度O(1)。
  • 相关阅读:
    Eclipse Clojure 开发插件
    leiningen安装记录
    XX-NET史上最详细完整教程
    使用Chrome浏览器设置XX-net的方法
    Sublime text 3搭建Python开发环境及常用插件安装
    python集合(set)类型的操作
    python编码问题在此终结
    新版的 selenium已经放弃PhantomJS改用Chorme headless
    python爬虫积累(一)--------selenium+python+PhantomJS的使用(转)
    Pyinstaller打包selenium去除chromedriver黑框问题解决!!!
  • 原文地址:https://www.cnblogs.com/fuxuyang/p/11144333.html
Copyright © 2011-2022 走看看