Jeff数据结构与算法收官之战:图及常见的十种算法(四天结束战斗!)

平衡二叉树:

前提是有序的二叉树,它的左右子树的高相差不超过1,它的所有的子树也要满足这个要求。
如果一个有序二叉树呈单支状(接近单支),它的效率接近链表,因此只有达到平衡时它的效率才最高。
由于节点的位置受值的影响,因此只能进行调整,而不能强行修改。

二叉树不平衡的基础原因:
      x                            y 
     / \                         /   \
    y   t1  以为轴向右旋转       z     x
   / \                         / \   / \
  Z   t2                      t3 t4 t2 t1
 / \
t4  t3

  x                                  y
 / \                               /   \
t1  y                             x     z
   / \      心y为轴向左旋转       / \   / \
  t2  z                         t1 t2 t3 t4
     / \                             
    t3  t4

      x                 x                z
     / \               / \             /   \
    y   t1            z   t1          y     x
   / \               / \             / \   / \
  t4  z             y   t2          t4 t3 t2 t1
     /  \          / \
    t3   t2       t4  t3
以z为轴向左旋转    以z为轴向右旋转    最终达到平衡

    x                 x                   z
   / \               / \                /   \
  t1  y             t1  z              x     y
     / \               / \            / \   / \
    z  t4             t2  y          t1 t2 t3  t4
   / \                   / \
  t2  t3                t3 t4
以z为轴向右旋转    心z为轴向左旋转

红黑树:

也一种自平衡的二叉树,它不是根据子树的高度来调整平衡的,而是给节点设置一个颜色,来达到平衡。
优点:插入与删除的效率,比AVL树要高。
缺点:没有AVL均匀,查找效率没AVL树高。

图(Graph)型结构:

什么图型结构:由顶点的有穷且非空和顶点之间边的集合.
通常表示:G(V,E),G表示一个图,V是图中顶点集合(元素),E是图中边(元素之间的关系)的集合。

无向图:

  边用(A,B)方式表示,点与点之间是互通的。
  在无向图中,任意两个顶点之间都有边,该图称为无向完全图,则含有n个顶点的无向完全图有,n*(n-1)/2条边。

有向图:
边用<A,B>方式表示,仅仅是A到到B点,有向图的边也叫弧,A是弧尾,B是弧头。
在有向图中,任意两个顶点之间都方向相反的两条弧,这种图叫有向完全图,则含有n个顶点的有向完全图有,n*(n-1)。
注意:不存在顶点到自身的边,且一条边不重复出现,这种图叫简单图,数据结构中只研究简单图。

图的点多边少的图叫稀疏图,反之的叫稠密图,图的点与点之间边带数据,这些数据叫作边的权重,带权重的图被称为网。

依附于顶点的边的数量叫作顶的度,有向图双分为出度(从顶出的的弧的数量)和入度(指向顶点的弧的数量)。

路径:顶点到顶点经过的边叫路径,边的数量叫路径的长度。

第一个顶点到最后一个顶的路径是相同的,这种路径叫回路或者环。
序列顶点中不重复出现的路径称为简单路径,除了第一个顶点和最后一个顶点,其余顶点不重复出现的回路叫简单回路。

如果顶点V到顶点V1有路径,则称V和V1是连通的,如果图中和任意顶点之间是连通的,则称图为连通图,如果一个图中有n个顶点那么至少需要n-1条边才能达到连通图,仅需要n-1边的连通叫生成树,如果再配合上权重,代价最的叫最小生成树。

树的存储结构:

阾接矩阵:

  用一个一维数组来存储n个顶点,用一个n*n二维数组来存储边。
  char V[n] = {A,B,C,D,E,F,G};
        A  B  C  D  E  F  G
     A [0][0][0][1][1][0][0]
     B [0][0][0][0][0][0][0]
     C [0][0][0][0][0][0][0]
     D [1][0][0][0][0][0][0]
     E [0][0][0][0][0][0][0]
     F [0][0][0][0][0][0][0]
     G [0][0][0][0][0][0][0]
     二维数组中E[i][j]的值为1,则表示项V[i],到顶点V[j]有边。
     注意:由于不存在自己到自己的边,主对角线上的值为假。
     如果存储的是无向图则二维数组中的值沿主对角线对称,可以压缩为一维数组(参看矩阵压缩)。

阾接矩阵的优点是可以方便计算顶点的入度和出度,但缺点是当图是稀疏图时,会非常浪费存储空间。

阾接表:

  边:
     顶点下标
     下一条边的地址
  顶点:
     数据
     指向第一条边的指针
  图:
     由顶点组成的数组            
     顶点数量cnt
  优点:可以节约存储空间,计算入度麻烦。

十字链表:

  边:
     弧尾下标
     弧头下标
     指向相同弧尾的下一条边
     指向相同弧头的下一条边

  顶点:
     数据
     指向第一条边的指针
     指向入度的边
  图:
     由顶点组成的数组            
     顶点数量cnt

阾接多重表:

  是一种专门存储无向图的一种结构。
  边:
     i,j 两个互相依附的顶点的下标
     inext 指向下一个依附i项点的边
     jnext 指向下一个依附j项点的边

  顶点:
     数据 
     指向与顶点有关系的一条边。
     
  图:
     由顶点组成的数组。
     顶点数量

算法:

输入: 算法具有0个或多个输入
输出: 算法至少有1个或多个输出
有穷性: 算法在有限的步骤之后会自动结束而不会无限循环,并且每一个步骤可以在可接受的时间内完成
确定性:算法中的每一步都有确定的含义,不会出现二义性
可行性:算法的每一步都是可行的,也就是说每一步都能够执行有限的次数完

如果评价一个算法:
时间复杂度:由于计算机的性能不同,无法准确统计出算法执行所需要的时间。
因此我们用算法执行的次数来代表算法的时间复杂度,O(公式),一般忽略常数。

  常见的时间复杂度:
     // O(1)
     printf("%d",i); 
     // O(logn)
     for(int i=n; i>=0; i=i/2)
     {
        printf("%d",i);
     }
     // O(n)
     for(int i=0; i<n; i++)
     {
        printf("%d",i);
     }
     // O(nlogn)
     for(int j=0; j<n; j++)
     {
        for(int i=n; i>=0; i=i/2)
        {
           printf("%d",i);
        }
     }
     // O(n^2)
     for(int i=0; i<n; i++)
     {
        for(int j=0; j<n; j++)
        {
           printf("%d",i*j);
        }
     }

查找算法:

顺序查找:

  对待查找的数据没有要求,时间复杂度: O(n)

二分查找:

  对待查找的数据必须有序,时间复杂度: O(logn)

块查找:

  是一种数据处理的思想,不是特定的算法,当数据量过多时,可以先把数据进行分块处理,然后再进行查找,例如英语词典。

哈希查找:

  数据 经过哈希函数 计算出数据在哈希表中的位置,然后标记,方便之后的查找,它的时间复试度最快能达到:O(1)。
  但是该算法有很大局限性,不适合浮点型、字符串型数据,需要额外的存储空间,空间复杂度高,是一种典型的用空间换取时间的算法。

哈希函数设计方法:

     直接定址法:把数据直接当作数组的下标。
     数字分析法:分析数据的特点来设计哈希,常用的方法就是找到最大值与最小值,最大值-最小值+1来确定哈希表的长度,数据-最小值访问哈希表。

排序算法:

在这里插入图片描述

冒泡:数据左右进行比较,把最大的数据交换到最后,特点是该算法对数据的有序性敏感,在排序过程中可以立即发现已经完成。

选择:假定最开始的位置是最小值并记录下标min,然后与后面的数据进行比较,如果有比以min为下标的数据小的则min的更新,最后如果min的如果发生改变,则交换min与最开始位置的数据,虽然时间复杂度挺高的,但数据交换的次数比较小,因此实际运行速度并不慢(数据交换比数据比较耗时)。

插入:把数据看作两部分,一分部是有序,把剩余的数据逐个插入进行,适合对已经排序后的数据,新增数据并排序。

希尔:是插入排序的增加版,由于插入排序时,数据移动的速度比较发慢,所以增加了增量的概念,以此来提高排序速度。

快速:找到一个标杆,一面从左找比标杆大的数据,找到后把放在标杆的右边,另一个从右边找比标杆小的数据,找到后把放在标杆的左边,最终标杆左边的数据都比它小,右边的数据都比它大,这样就整体有序,然后按同样的方法排序标杆左边的数据和标杆右边的数据。

快速:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

归并:建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。

堆:堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

计数:计数排序不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。

桶:桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。桶排序 (Bucket sort)的工作的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排)。

基数:属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或binsort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用。

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
编辑推荐  Sedgewick之巨著,与高德纳TAOCP一脉相承  几十年多次修订,经久不衰的畅销书  涵盖所有程序员必须掌握的50种算法 内容简介    《算法(第4版)》全面讲述算法数据结构的必备知识,具有以下几大特色。    1、 算法领域的经典参考书:Sedgewick畅销著作的*版,反映了经过几十年演化而成的算法核心知识体系    2、内容全面:全面论述排序、搜索、图处理和字符串处理的算法数据结构,涵盖每位程序员应知应会的50种算法    3、全新修订的代码:全新的Java实现代码,采用模块化的编程风格,所有代码均可供读者使用    4、与实际应用相结合:在重要的科学、工程和商业应用环境下探讨算法,给出了算法的实际代码,而非同类著作常用的伪代码   5、富于智力趣味性:简明扼要的内容,用丰富的视觉元素展示的示例,精心设计的代码,详尽的历史和科学背景知识,各种难度的练习,这一切都将使读者手不释卷    6、科学的方法:用合适的数学模型精确地讨论算法性能,这些模型是在真实环境中得到验证的   7、与网络相结合:配套网站algs4.cs.princeton.edu提供了本书内容的摘要及相关的代码、测试数据、编程练习、教学课件等资源 作者简介    Robert Sedgewick,斯坦福大学博士,导师为Donald E.Knuth,从1985年开始一直担任普林斯顿大学计算机科学系教授,曾任该系主任,也是AdobeSystems公司董事会成员,曾在Xerox PARC、国防分析研究所(Institute for DefenseAnalyses)和法国国家信息与自动化研究所(INRIA)从事研究工作。他的研究方向包括解析组合学、数据结构算法的分析与设计、程序可视化等。    KevinWayne,康奈尔大学博士,普林斯顿大学计算机科学系高级讲师,研究方向包括算法的设计、分析和实现,特别是图和离散优化。 目  录 第1章  基础 1.1 基础编程模型 1.1.1 Java程序的基本结构 1.1.2 原始数据类型与表达式 1.1.3  语句 1.1.4  简便记法 1.1.5  数组 1.1.6  静态方法 1.1.7  API 1.1.8  字符串 1.1.9  输入输出 1.1.10  二分查找 1.1.11  展望 1.2  数据抽象 1.2.1  使用抽象数据类型 1.2.2  抽象数据类型举例 1.2.3  抽象数据类型的实现 1.2.4  更多抽象数据类型的实现 1.2.5  数据类型的设计 1.3  背包、队列和栈 1.3.1  API 1.3.2  集合类数据类型的实现 1.3.3  链表 1.3.4  综述 1.4  算法分析 1.4.1  科学方法 1.4.2  观察 1.4.3  数学模型 1.4.4  增长数量级的分类 1.4.5  设计更快的算法 1.4.6  倍率实验 1.4.7  注意事项 1.4.8  处理对于输入的依赖 1.4.9  内存 1.4.10  展望 1.5  案例研究:union-find算法 1.5.1  动态连通性 1.5.2  实现 1.5.3  展望 第2章  排序 2.1  初级排序算法 2.1.1  游戏规则 2.1.2  选择排序 2.1.3  插入排序 2.1.4  排序算法的可视化 2.1.5  比较两种排序算法 2.1.6  希尔排序 2.2  归并排序 2.2.1  原地归并的抽象方法 2.2.2  自顶向下的归并排序 2.2.3  自底向上的归并排序 2.2.4  排序算法的复杂度 2.3  快速排序 2.3.1  基本算法 2.3.2  性能特点 2.3.3  算法改进 2.4  优先队列 2.4.1  API 2.4.2  初级实现 2.4.3  堆的定义 2.4.4  堆的算法 2.4.5  堆排序 2.5  应用 2.5.1  将各种数据排序 2.5.2  我应该使用哪种排序算法 2.5.3  问题的归约 2.5.4  排序应用一览 第3章 查找 3.1 符号表 3.1.1 API 3.1.2 有序符号表 3.1.3 用例举例 3.1.4 无序链表中的顺序查找 3.1.5 有序数组中的二分查找 3.1.6 对二分查找的分析 3.1.7 预览 3.2 二叉查找树 3.2.1 基本实现 3.2.2 分析 3.2.3 有序性相关的方法与删除操作 3.3 平衡查找树 3.3.1 2-3查找树 3.3.2 红黑二叉查找树 3.3.3 实现 3.3.4 删除操作 3.3.5 红黑树的性质 3.4 散列表 3.4.1 散列函数 3.4.2 基于拉链法的散列表 3.4.3 基于线性探测法的散列表 3.4.4 调整数组大小 3.4.5 内存使用 3.5 应用 3.5.1 我应该使用符号表的哪种实现 3.5.2 集合的API 3.5.3 字典类用例 3.5.4 索引类用例 3.5.5 稀疏向量 第4章  图 4.1  无向图 4.1.1  术语表 4.1.2  表示无向图的数据类型 4.1.3  深度优先搜索 4.1.4  寻找路径 4.1.5  广度优先搜索 4.1.6  连通分量 4.1.7  符号图 4.1.8  总结 4.2  有向图 4.2.1  术语 4.2.2  有向图的数据类型 4.2.3  有向图中的可达性 4.2.4  环和有向无环图 4.2.5  有向图中的强连通性 4.2.6  总结 4.3  最小生成树 4.3.1  原理 4.3.2  加权无向图的数据类型 4.3.3  最小生成树的API和测试用例 4.3.4  Prim算法 4.3.5  Prim算法的即时实现 4.3.6  Kruskal算法 4.3.7  展望 4.4  最短路径 4.4.1  最短路径的性质 4.4.2  加权有向图的数据结构 4.4.3  最短路径算法的理论基础 4.4.4  Dijkstra算法 4.4.5  无环加权有向图中的最短路径算法 4.4.6  一般加权有向图中的最短路径问题 4.4.7  展望 第5章  字符串 5.1  字符串排序 5.1.1  键索引计数法 5.1.2  低位优先的字符串排序 5.1.3  高位优先的字符串排序 5.1.4  三向字符串快速排序 5.1.5  字符串排序算法的选择 5.2  单词查找树 5.2.1  单词查找树 5.2.2  单词查找树的性质 5.2.3  三向单词查找树 5.2.4  三向单词查找树的性质 5.2.5  应该使用字符串符号表的哪种实现 5.3  子字符串查找 5.3.1  历史简介 5.3.2  暴力子字符串查找算法 5.3.3  Knuth-Morris-Pratt子字符串查找算法 5.3.4  Boyer-Moore字符串查找算法 5.3.5  Rabin-Karp指纹字符串查找算法 5.3.6  总结 5.4  正则表达式 5.4.1  使用正则表达式描述模式 5.4.2  缩略写法 5.4.3  正则表达式的实际应用 5.4.4  非确定有限状态自动机 5.4.5  模拟NFA的运行 5.4.6  构造与正则表达式对应的 5.5  数据压缩 5.5.1  游戏规则 5.5.2  读写二进制数据 5.5.3  局限 5.5.4  热身运动:基因组 5.5.5  游程编码 5.5.6  霍夫曼压缩 第6章  背景 索引
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值