zoukankan      html  css  js  c++  java
  • C++算法之——常用算法总结

    http://blog.sina.com.cn/s/blog_61bebe480100v7c7.html

    基本的C++算法分为三类:排序算法、树算法、图算法

    算法思想有三种:递推、分治、动态规划 以及 贪心算法。
    本文将简要介绍上面三类算法,介绍时穿插介绍算法思想。
     
    一、排序算法
     
    1、基本O(n^2)排序算法: (对基本排序算法的时间复杂度分析主要考虑  比较次数、数据交换次数)
    冒泡排序:针对数组、本地排序、需要交换数据。O(1)额外空间
    选择排序:一般针对数组、本地排序、需要交换数据。O(1)的额外空间
    插入排序:可以是针对数组的本地排序,此时需要移动大片数据,但是比较次数是O(N*logN)。如果是针对链表,比较次数是O(N^2),但是不需要交换数据。
     
    注意:一般排序都是针对数组的本地排序,数组与链表相比,可以随机访问,空间使用效率更高(链表需要存放指针),而链表一般对于插入与删除操作有更好的性能。
     
    2. O(N*logN)算法
    快速排序:针对数组的本地排序,时间复杂度平均O(N*logN),最坏时O(N^2)。空间复杂度O(1)
    归并排序:可以针对数组,也可以针对链表。针对数组时时间复杂度为O(N*logN),空间复杂度为O(N)
     
    3. 堆排序
    1991年计算机先驱奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德(Robert W.Floyd)和威廉姆斯(J.Williams)在1964年共同发明了著名的堆排序算法( Heap Sort )
    堆是一种非常高效的数据结构,可以用数组来表示堆。
     
    堆排序是针对数组的本地排序,时间复杂度为O(N*logN),空间复杂度为O(1)
     
    对于降序排列时用最小堆,首先建立堆,然后将第一个元素(堆头)与组后一个元素交换。找到了排列的最后一个元素,然后再调整前N-1个元素为最小堆,依次类推,即完成排序。
     
    注意:堆得建立, 堆的建立的时间复杂度为O(N*logN),可以有多种方法建立堆
     
    4. 基数排序
    数据的取值范围不大,利用bitmap
     
    5. 外排序
    归并排序,多路归并排序(利用堆实现多路归并排序)
    使用堆进行多路排序时,堆中的每个元素同附加上一个域,存放该元素来自那一路
     
    堆一般还可以用于TopK算法,求TopK最大可以使用K个元素的最小堆维护K个最大元素,对原始数组扫描一遍即可。
     
    二、树的算法
    树一般用链表实现,通常用树数据结构实现数据的快速插入、删除、查找。
     
    1. 平衡二叉查找树
    RB-Tree、 AVL、 Treap、 伸展树(无需存放额外信息)
     
    2. B树
    用于建立文件系统或数据库的索引。B树的设计目标是减少IO访问次数。B树也是一棵平衡树
     
    3. 二项树、二项堆、费波那奇堆
     
    三、图的算法
    1. 图的表示
    有向图、无向图 的 邻接表表示、矩阵表示
     
    2. 广度优先搜索、深度优先搜索
    广度优先搜索(BFS):找到从单个源点到所有点得最短路径,适用于有向图、无向图。算法发杂度为O(V+E),注意算法对应图的边没有权重。算法使用队列实现广度优先。算法使用三个辅助变量、color、paraent、distance数组。搜索后的parent构成广度优先树
     
    深度优先搜索(DFS):可以随意从一个节点开始,遍历树的所有节点,使用于有向图、无向图。搜索构成森林。算法通过递归方式实现,依次递归完成后可能只搜索整个连通树的部分节点,因此需要从新任意选择一个节点从新开始DFS,整个搜索结果构成搜索森林。算法使用三个辅助变量:color,v,f。v表示搜索到该节点时间,f表示该节点的邻接节点都扫描完成的时间。
     
    注意DFS可以完成拓扑排序。利用f出现时间的降序就是拓扑序,可以在深度优先搜索的过程中得到该排序。
    DFS算法还可以用于发现强连通分支。
     
    3. 最小生成树
     
    针对无向连通图的,常见的算法有 Kruskal算法和Prim算法
     
    Kruskal算法
    将所有的边非降序排列,所有的顶点初始化为不相交集合,每次取一个边,如果该边属于不同的集合,则该边加入解集,同时更新不想交集合。注意:不想交集合实现有专门的数据结构。
     
    Prim算法
    该算法与Dijkstra算法类似,每次加入已覆盖集合A和未覆盖集合B之间最短的边。
     
     
     
    4. 最短路径
     
    有权值的最短路径问题。可以是有向图,可以是无向图。权值可以为负值。
     
    变种:点与点之间最短路径、固定终点最短路径、所有点之间最短路径、最长路径(将权值去负值利用bellman-ford算法即可)
     
    Bellman-Ford算法
    惊醒V-1遍松弛遍历,每次遍历,按照一定顺序,依次将所有的边松弛一遍。结束后,对所有的边进行一次check,如果有边不符合松弛条件,则返回false,表明图中存在负权值的环(该特性可以用于检测有向图中得环),算法复杂度O(VE)
     
    Dijkstra算法
    只能针对于正值的边。算法复杂度O(V^2)
     
     
    5. 求所有点之间的最短路径
    矩阵上得动态规划算法。
    Floyd-Warshall算法,d_ij(k) 表示从顶点i到顶点j,中间节点只包含{1、2、... k}的最短路径。d_ij(n)即为所求。
    Floyd-Warshall算法可以用于求任意两个顶点是否可达
     
     
  • 相关阅读:
    49. 字母异位词分组
    73. 矩阵置零
    Razor语法问题(foreach里面嵌套if)
    多线程问题
    Get json formatted string from web by sending HttpWebRequest and then deserialize it to get needed data
    How to execute tons of tasks parallelly with TPL method?
    How to sort the dictionary by the value field
    How to customize the console applicaton
    What is the difference for delete/truncate/drop
    How to call C/C++ sytle function from C# solution?
  • 原文地址:https://www.cnblogs.com/dps001/p/4440725.html
Copyright © 2011-2022 走看看