数据结构(二)

  1. 树的表示法:双亲表示法、孩子表示法、孩子兄弟表示法
  2. 树与二叉树的转化
  3. 树的遍历:先根、后根
  4. 森林与二叉树的转化
  5. 森林的遍历:先序、中序、后序

算法邻接矩阵邻接表思想用途
DFS/BFSO(V2)O(V^2)O(V2)O(V+E)O(V+E)O(V+E)-图的遍历
PrimO(V2)O(V^2)O(V2)O(V+E)O(V+E)O(V+E)点贪心+BFS最小生成树
KruskalO(Elog⁡E)O(E\log{E})O(ElogE)O(Elog⁡E)O(E\log{E})O(ElogE)边贪心最小生成树
DijkstraO(V2)O(V^2)O(V2)O(V+E)O(V+E)O(V+E)贪心+BFS单源最短路
FloydO(V3)O(V^3)O(V3)-DP多源最短路
TopoO(V2)O(V^2)O(V2)O(V+E)O(V+E)O(V+E)-AOV,AOE
关键路径O(V2)O(V^2)O(V2)O(V+E)O(V+E)O(V+E)BFS-

查找

查找方式ASL
顺序查找(n+1)2\frac{(n+1)}{2}2(n+1)
折半查找接近于log⁡n+1\log{n}+1logn+1*
分块(索引)查找如果使用顺序查找,则是d2+n2d+1\frac{d}{2}+\frac{n}{2d}+12d+2dn+1,最优分块dddn\sqrt{n}n
哈希查找散列函数、处理冲突方式、装填因子α\alphaα有关

*可以利用二叉判定树的性质证明。

查找数据结构

上述的查找方式基本上是静态查找,以下的数据结构可以用于动态查找。自己看书学一学就会了。

BST

  1. 增加元素
    在查找失败的叶子节点处,增加一个新的节点就好了。
  2. 删除元素
    如果是叶子节点,则直接删除
    如果是非叶子节点,则用直接前驱或后继替代当前节点的位置,然后转而将直接前驱或后继删除,这样递归下去的话,一定能转化为删除叶子节点。

AVL

由于BST对于不同插入序列构造出来的BST都不同。所以可能会退化为链表。
通过旋转操作使得BST平衡。操作与BST树相同,只是多了个旋转操作。

基本概念:

  1. 平衡因子:
    右子树高度减去左子树高度
  2. 平衡:
    平衡因子在[−1,1][-1,1][1,1]之间。
  3. 旋转
    分为LL,LR,RR,RL旋转

B-树

  1. 查找元素
    与BST类似
  2. 增加元素
    与BST相同,若节点个数为m,则需要分裂。
  3. 删除元素
    与BST相同。
    如果节点个数为m/2-1,则需要向兄弟节点借节点。
    如果兄弟不够借,则兄弟与父节点合并。如果合并导致高度变化,则用爷爷与父亲兄弟合并,来增加树的高度。
  4. B-树元素与高度之间的关系
    高度为hhh的B树含有元素最多有mh−1m^h-1mh1个节点。最少含有2m2h−1+m2−32\frac{m}{2}^{h-1}+\frac{m}{2}-322mh1+2m3个节点。

B+树

可以索引查找,也可以顺序查找

排序

排序名称平均时间复杂度最好时间复杂度最坏时间复杂度空间复杂度稳定性元素比较次数原始序列
插入排序O(n2)O(n^2)O(n2)O(n)O(n)O(n)O(n2)O(n^2)O(n2)O(1)O(1)O(1)稳定(n−1)(n-1)(n1)-((n−1)n2)(\frac{(n-1)n}{2})(2(n1)n)有关
希尔排序O(n1.3)O(n^{1.3})O(n1.3)O(n)O(n)O(n)O(n2)O(n^2)O(n2)O(1)O(1)O(1)不稳定-有关
冒泡排序O(n2)O(n^2)O(n2)O(n)O(n)O(n)O(n2)O(n^2)O(n2)O(1)O(1)O(1)稳定(n−1)(n-1)(n1)-((n−1)n2)(\frac{(n-1)n}{2})(2(n1)n)有关
快速排序O(nlog⁡n)O(n\log{n})O(nlogn)O(nlog⁡n)O(n\log{n})O(nlogn)O(n2)O(n^2)O(n2)O(log⁡n)O(\log{n})O(logn)-O(n)O(n)O(n)不稳定-有关
选择排序O(n2)O(n^2)O(n2)O(n2)O(n^2)O(n2)O(n2)O(n^2)O(n2)O(1)O(1)O(1)不稳定(n−1)n2\frac{(n-1)n}{2}2(n1)n无关
堆排序O(nlog⁡n)O(n\log{n})O(nlogn)O(nlog⁡n)O(n\log{n})O(nlogn)O(nlog⁡n)O(n\log{n})O(nlogn)O(1)O(1)O(1)不稳定-无关
归并排序O(nlog⁡n)O(n\log{n})O(nlogn)O(nlog⁡n)O(n\log{n})O(nlogn)O(nlog⁡n)O(n\log{n})O(nlogn)O(n)O(n)O(n)稳定-无关
基数排序O(d(r+n))O(d(r+n))O(d(r+n))O(d(r+n))O(d(r+n))O(d(r+n))O(d(r+n))O(d(r+n))O(d(r+n))O(r)O(r)O(r)稳定000无关

排序概述

  • 时间复杂度与空间复杂度
  • 稳定性:不用来判断排序算法的优劣,只是一种需求。
  • 内部排序主要有

插入排序:将要排序的元素插入到已经有序的序列中
交换排序:不断的交换元素使得序列有序
选择排序:每次选择一个元素放到最终的位置上
归并排序:有序表的合并
基数排序:不基于比较元素的排序

插入排序

简单插入排序

def:插入排序是通过将当前元素插入之前有序列表的排序方法。

特点

  1. 排序速度受到原始序列的影响。当基本有序的时候,速度接近O(n)O(n)O(n),当接近逆序的时候,速度接近O(n2)O(n^2)O(n2)
  2. 稳定

优化:折半排入排序,因为当前插入元素之前的元素都是有序的,所以我们可以通过二分查找来替代顺序查找。但是,该方法只能降低元素的比较次数,而不能降低元素的移动次数。所以平均时间复杂度还是O(n2)O(n^2)O(n2)

希尔排序(分组插入排序)

原理:因为当序列是基本有序的时候,简单插入排序的效率是线性的。所以可以通过分组插入的方法,让序列不断的接近有序的状态从而降低排序时间。

实现:通过一个因子ddd来控制组内元素间隔的距离。并且不断的减小ddd,最后使得d=1d=1d=1的时候,退化为直接插入排序。

void ShellSort(int *a,int n){
    for(int d = n/2;d>=1;d/=2){	//控制距离的因子d
        for(int i=d;i<n;i++){	//组内使用直接插入排序
            int tmp = a[i] , j;
            for(j = i-d;j>=0&&a[j]>tmp;j-=d)
                a[j+d] = a[j];
            a[j+d] = tmp;
        }
    }
}

交换排序

冒泡排序

特点:

  1. 排序的趟数、排序速度与初始序列有关。
  2. 每趟排序之后,一定有一个元素在最终的位置上。

快速排序

思想:分块
递归调用函数的时候,每次都把区间分成左右区间。左区间的元素个数全部小于该元素,右区间的元素全部大于等于该元素。(相等元素出现的位置与代码有关)

特点:

  1. 排序的趟数、速度、空间与初始序列有关
  2. 每趟排序之后,一定有一个元素在最终的位置上;在同一层的总用时是O(n)O(n)O(n)

代码:

int partition(int *a,int l,int r){
    int tmp = a[l];	//基准元素
    //! l不能先++
    while(l<r){
        while(l<r&&a[r]>=tmp) r--;
        a[l] = a[r];
        while(l<r&&a[l]<tmp) l++;
        a[r] = a[l];
    }
    a[l] = tmp;
    return l;
}

void qsort(int *a,int l,int r){
    if(l<r){
        int mid = partition(a,l,r);	//分割区间
        qsort(a,l,mid-1);	//排序左边
        qsort(a,mid+1,r);	//排序右边
    }
}

选择排序

简单选择排序

特点:

  1. 简单排序算法中唯一一个不稳定的算法。
  2. 排序时间与原始序列无关。

堆排序

通过数据结构堆(heap)的排序。

时间复杂度分析:

  1. 建堆O(n)O(n)O(n),从第一个非叶子节点开始向下调整。考虑每次都调整到叶子节点,调整的次数为Tn=20×h+21×(h−1)+22×(h−2)+⋯+2h×1Tn=2^0\times h +2^1\times (h-1)+2^2\times (h-2)+\dots+2^h\times 1Tn=20×h+21×(h1)+22×(h2)++2h×1,计算之后发现是O(n)O(n)O(n)
  2. 排序O(nlog⁡n)O(n\log{n})O(nlogn),每取一个元素是O(log⁡n)O(\log{n})O(logn),取nnn个元素当然是O(nlog⁡n)O(n\log{n})O(nlogn)的。

所以时间复杂度是O(nlog⁡n)O(n\log{n})O(nlogn)的。

特点:

  1. 简单排序算法中唯一一个不稳定的算法。
  2. 排序时间与原始序列无关。只会影响常数的大小。

归并排序

基于有序表的合并算法。需要额外开辟O(n)O(n)O(n)个辅助空间。

特点:

  1. 与原始序列无关,算法稳定。
  2. 可以用于外部排序

基数排序

通过分散和收集两个操作来完成。

有两种排序的方法:低位优先和高位优先。

同一优先级中,通过其他不同的优先级来区分。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值