Preface
面向课内考试的归纳功利化整理。
*关于数据结构的形而上
参见ch1.pdf,P1-P34.
数据结构种类
线性结构,层次结构,群结构。(记住这仨词儿)
算法复杂度分析
程序步
注释:程序步数为0
声明语句:程序步数为0
表达式、赋值语句:程序步数为1
循环语句:循环控制语句每次执行的程序步数为1
注意:increment, decrement, self-assignment 全算一步。
你说的有道理,但答案是这么写的(该扣分还是要扣)。
———— 助教
…
渐进复杂度分析
$O(f(n))$而已,即决定数量级。
Ontario.
String
String の Class 实现(基础部分)1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| #ifndef ASTRING_H #define ASTRING_H #define defaultSize = 128; class AString {
private: char *ch; int curLength; int maxSize; public: AString(int sz = defaultSize); AString(const char *init ); AString(const AString& ob); ~AString() {delete [ ]ch; } int Length() const { return curLength; } Astring& operator() (int pos, int len); bool operator == (AString& ob) const { return strcmp (ch, ob.ch) == 0; } bool operator != (AString& ob) const { return strcmp (ch, ob.ch) != 0; } bool operator ! () const { return curLength == 0; } AString& operator = (AString& ob); AString& operator += (AString& ob); char& operator [ ] (int i); int Find (AString& pat, int start) const; }; AString::AString(int sz) {
maxSize = sz; ch = new char[maxSize+1]; if (ch == NULL) { cerr << “存储分配错!\n”; exit(1); } curLength = 0; ch[0] = ‘\0’; }; AString::AString(const char *init) {
int len = strlen(init); maxSize = (len > defaultSize) ? len : defaultSize; ch = new char[maxSize+1]; if (ch == NULL) { cerr << “存储分配错 ! \n”; exit(1); } curLength = len; strcpy(ch, init); }; AString :: AString(const AString& ob) { maxSize = ob.maxSize; ch = new char[maxSize +1]; if (ch == NULL) { cerr << “存储分配错! \n”; exit(1); } curLength = ob.curLength; strcpy(ch, ob.ch); }; AString AString::operator () (int pos, int len) {
AString temp; if (pos >= 0 && pos+len-1 < maxSize && len > 0) { if (pos+len-1 >= curLength) len = curLength - pos; temp.curLength = len; for (int i = 0, j = pos; i < len; i++, j++) temp.ch[i] = ch[j]; temp.ch[len] = ‘\0’; } return temp; }; AString& AString::operator = (const AString& ob) { if (&ob != this) { delete []ch; ch = new char[maxSize+1]; if (ch == NULL) { cerr << “存储分配失败!\n ”; exit(1); } curLength = ob.curLength; strcpy(ch,ob.ch); } else cout << “字符串自身赋值出错!\n”; return this; }; char AString::operator [ ] (int i) {
if (i < 0 || i >= curLength) { cout << “字符串下标超界!\n ”; exit(1); } return ch[i]; }; AString& AString::operator += (const AString& ob) { char *temp = ch; int n = curLength + ob.curLength; int m = (maxSize >= n) ? maxSize : n; ch = new char[m]; if (ch == NULL) { cerr << “存储分配错!\n ”; exit(1); } maxSize = m; curLength = n; strcpy(ch, temp); strcat(ch, ob.ch); delete []temp; return this; };
|
字符串匹配のKMP算法
OI wiki教程(包括一些基于KMP基本思想的拓展思考)
涉及问题索引:
- 前缀函数求解
- KMP算法
- 字符串周期
- 前缀出现次数统计
- 本质不同子串统计
- 字符串分割成周期
前缀函数状态转移

KMP

比较接地气的详细讲解
广义表
完全不知道制造出这个ADT有什么可说的。。。
头是头,尾是表里其他元素组成的表。
Node 三种类型: 表头,原子,子表
就是Scheme里的List (Python 里其实也是这玩意)
深度定义:其实就是最深的套几层括号。
实现的时候要引用计数,不然多引用的时候,删子表会炸。
Tree
Binary Tree
- 若二叉树结点的层次从 1 开始, 则在二叉树的第 i 层最多有 2i-1 个结点。
- 深度为 k 的二叉树最少有 k 个结点,最多有 2k-1个结点。
- 对任何一棵二叉树,如果其叶结点有 $n_0$ 个, 度为 2 的非叶结点有 $n_2$ 个, 则有$n0=n2+1$
- 具有 n (n≥0) 个结点的完全二叉树的深度为 $log2(n+1)$
线性映射
若$i = 1$, 则 i 无双亲
若$i > 1$, 则 i 的双亲为$[i/2]$
若$2i <= n$, 则 i 的左子女为 $2 i$
若$2i+1 <= n$, 则 i 的右子女为$2i+1$
若 i 为奇数, 且$i != 1$, 则其左兄弟为$i-1$
若 i 为偶数, 且$i != n$, 则其右兄弟为$i+1$
四种遍历
前序中序确定树
三序线索化二叉树
这*东西有什么用?见ppt?
一般树存储
留了一个不知道有什么用的子女兄弟存储(见ppt),剩下的都是废话。
遍历
深搜,广搜,废话连篇,略。
Forest
遍历关注一下广度,就是子女兄弟法。
Heap
二叉堆
以及对顶堆。
https://oi-wiki.org/ds/binary-heap/
Huffman tree
没啥意思,构造就是取小merge。
Reference
NJU DS lwj