DSAlg Cheatsheet

省流:

#include<iostream.h>
#include<string.h>
#include<stdio.h>
#include “stack.h”
const int Maxlength = 100; // max expression length
void PrintMatchedPairs(char *expr)
{   Stack<int> s(Maxlength);
    int j, length = strlen(expr);
    for ( int i = 1; i <= length; i++)
    {   if ( expr[i- 1]= =‘(‘) s.Add(i);
       else if (expr[i- 1]= =‘)’)
          try {s.Delete(j);   cout ≪j≪‘ ‘ ≪i≪endl;}
          catch (OutOfBounds)
             {cout ≪ “No Match for right parenthesis”
                   ≪ “ at “≪ i ≪ endl;}
    }
    while ( !s.IsEmpty ())
   {  s.Delete(j);
      cout≪ “No match for left parenthesis at “
          ≪ j ≪ endl;
  }}

chapter1

泛型,数学归纳法什么的,上学期离散。

chapter2

讲复杂度不讲主定理,这就是你软的数据结构与算法。

数数 for 算算数,比较平凡。

chapter3

栈和队列,典中典左闭右闭,招笑了。

一块空间开两个栈,叫对顶栈。另外还有个循环队列。

循环左移:直接移,每次移一圈,移动的是 mod gcd(n, P) = i 的,可以 O(n) 时间 O(1) 空间

出栈入栈确定操作过程:todo

chapter4

root 的 level 是 0。

满二叉树是满的,完全二叉树可以少最后几个叶子。

怎么这里又 0-index 了,左右儿子乘二加 1 or 2 就行了。[0] [1 2] [3 4 5 6] [7 8 9 ...]

三个序的非递归写法其实就是栈模拟递归。

左儿子右兄弟。

森林二叉树化:先左儿子右兄弟,然后连一排兄弟

线索树 Thread Tree:记一下左右指的是儿子还是前驱后继。递归建树返回子树最前最后就行。

注意这里的前驱后继是 先序 中序 后序 选一个

增长树:加叶子直到原来的节点度为 2。

外路径是到新的叶子之和,内路径是到原来的节点之和。带权是乘自己的权。

做法:贪心选两个最小的,相同优先选新的节点

huffman:所有新的节点用来编码

广义表何不是另一种左儿子右兄弟?

chapter 4.1

维护:左右儿子,值,左子树大小+1。

其实维护自己所在子树也行。

随意插入,删除就把两个子树 merge 起来接回去。

AVL:

任意子树左右树高不超过 1。需要维护往下的深度(树高)。

插两边转一次,中间转两次。里面是因为单旋不改变中间那个的深度,所以必须分开转。

删除差不多,删两边是双旋中间单旋。

B树:

每个节点 至多m 至少m/2上取整 个儿子,每两个儿子中夹着一个值。两个值中间夹着儿子或者外部节点。外部节点都在同一层。

算一下复杂度可以发现如果块内二分查找,总是 logn 的。

插入然后一路 split 上去,到根了就是深度加一。

删除:大于一半直接删,等于一半尝试借一个,借不了就和左/右合并(从父节点把中间夹的拿下来),可能往上继续合并

chapter5

开放寻址:注意删除只能懒惰删除

  • 线性探测 往后面放

  • 平方探测 往 +1 +4 +9 放

  • 双哈希 往 +hash(x), +2hash(x), +3hash(x) 放

rehash:大于70%

链地址:数组上挂链表

chapter 6

堆,保证自己大于两个儿子就行了。

建堆:

  1. 按倒着的 bfs 序调整,n

  2. 一个个往里插入,nlogn

chapter 7

并查集:

按秩/高度合并;路径压缩;

chapter 8

入度+出度

简单路,简单环

有向图 强连通分量scc:任意一对点相互可达

网络:边带权的图

邻接表。

无向图 邻接多重表 adjacency multilist:多加一个指针表示另一条边的往哪走。

有向图 邻接多重表 也称为十字链表:一样,然后节点记一下从哪走是出从哪是入

最小生成树:

kruskal 对边贪心(能选的最短的),prim 对点贪心(距离当前块最近的)

它们都采用了逐步求解(Grandy)的策略。

应该是 Greedy 贪心,每一步都贪心选择的意思。

网上一搜 Grandy 全是 njuse 丢不丢脸啊。

最短路:

dijkstra:类似 prim,找当前集合外到原点最近的

bellman-ford:每次 forall(u, v) disV = min(disV, disU + E(U, V))

ppt 里是每次开一层新数组

floyd:for all k,用 (i, k) (k, j) 尝试更新 dis(i, j)

活动网络 Activity Network

用顶点表示活动的网络(Activity On Vertex network)

拓扑排序:把入度 0 的删了。最后剩下的一定有环。

用边表示活动的网络(Activity On Edge network)

关键路径:最长的

求时间什么的:最早在前面的任务之后发生,最晚在后面之前,然后算一下。

chapter 9

内排序:内存足够用了

外排序:需要外存

不稳定的用斜体标出

另外锦标赛排序oiwiki说是不稳定的,课件里是稳定的,我觉得应该是稳定的。
实现的时候相同选左边就行了

其实选择排序也是复制一遍再选就稳定了,不过不重要

  1. 插入排序:找然后插入然后往后挪
  2. 折半插入排序:(二分)找然后插入然后往后挪,复杂度还是平方
  3. 希尔排序:隔 k={a b ... 1} 递减的间距做插排
  4. 冒泡排序:都会
  5. 快速排序:找个 pivot,划分,递归(或者栈模拟)
  6. 选择排序:选最小,第二小,……
  7. 锦标赛排序:另开一个类似堆的东西表示区间min,然后每次把最小值改成 max 一路更新上去
  8. 堆排序:就是建堆然后往外拿
  9. 归并排序:先递归再合并。也有非递归写法,for k 从左到右合并所有两个长 (2^k, 至多2^k) 的区间。
posted @   Xi'En  阅读(109)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
点击右上角即可分享
微信分享提示