├── LICENSE ├── Lectures ├── Lecture-1.1-数据结构与算法.md ├── Lecture-1.2-递归的思想与应用.md ├── Lecture-2.1-抽象数据类型ADT.md ├── Lecture-2.2-表ADT.md ├── Lecture-2.3-堆栈ADT.md ├── Lecture-2.4-队列ADT.md ├── Lecture-2.5-通用链表的实现.md ├── Lecture-3.1-树的预备知识.md ├── Lecture-3.2-二叉树.md ├── Lecture-3.3-查找树ADT(二叉查找树).md ├── Lecture-3.4-AVL树.md ├── Lecture-4.1-堆.md ├── Lecture-4.2-哈夫曼树与哈夫曼编码.md ├── Lecture-4.3-不相交集ADT.md ├── Lecture-6.1-排序.md ├── assets │ ├── 1523856492024.png │ ├── 1523856765127.png │ ├── 1524361788727.png │ ├── 1525163251581.png │ ├── 1525163382095.png │ ├── 1525163413002.png │ ├── 1525163442489.png │ ├── 1525163475986.png │ ├── 1525184315854.png │ ├── 1525184468714.png │ ├── 1525436823759.png │ ├── 1525436858718.png │ ├── 1525441443912.png │ ├── 1525596336625.png │ ├── 1525596423323.png │ └── 1525602421047.png └── rt-thread │ └── 1-内核对象模型.md ├── README.md ├── eclipse ├── DataStructuresCode │ ├── .cproject │ ├── .gitignore │ ├── .project │ ├── .settings │ │ ├── language.settings.xml │ │ ├── org.eclipse.cdt.managedbuilder.core.prefs │ │ └── org.eclipse.core.resources.prefs │ └── src │ │ ├── 01_1_Maxsubsequencesum_question.cpp │ │ ├── 01_2_Maximum_Subsequence_Sum.cpp │ │ ├── 01_3_BinarySearch.cpp │ │ ├── 02_1_List_Merge.cpp │ │ ├── 02_2_list_mult_add.cpp │ │ ├── 02_3_Reversing_Linked_List.cpp │ │ ├── 02_4_Pop_Sequence.cpp │ │ ├── 03_1_Tree_isomorphism.cpp │ │ ├── 03_2_List_Leaves.cpp │ │ ├── 03_3_Tree_Traversals_Again.cpp │ │ ├── 04_4_IsSameBinarySearchTree.cpp │ │ ├── 04_5_Root_of_AVL_Tree.cpp │ │ ├── 04_6_Complete_Binary_Search_Tree.cpp │ │ ├── 04_7_Binarysearch_tree_operation_set.cpp │ │ ├── 05_7_heap_path.cpp │ │ ├── 05_8_File_Transfer.cpp │ │ ├── 05_9_Huffman_Codes.cpp │ │ ├── C_advanced │ │ ├── dlist.c │ │ └── dlist.h │ │ ├── Project_01_recursive_function.cpp │ │ ├── computer_system │ │ ├── indirection_operator.c │ │ └── integer.cpp │ │ └── main.cpp └── SummerGift_Lib │ ├── .cproject │ ├── .gitignore │ ├── .project │ ├── .settings │ ├── language.settings.xml │ └── org.eclipse.cdt.managedbuilder.core.prefs │ ├── .tracecompass │ └── .project │ └── src │ ├── SmartPointer.h │ └── SummerGift_Lib.cpp └── sample_code ├── 27_二阶构造模式代码 ├── 27-1.cpp ├── 27-2.cpp ├── IntArray.cpp ├── IntArray.h └── main.cpp ├── 32_string_class ├── .cproject ├── .gitignore ├── .project ├── .settings │ ├── language.settings.xml │ └── org.eclipse.cdt.managedbuilder.core.prefs └── src │ └── String_Class.cpp └── list ├── IntArray.cpp ├── IntArray.h ├── function_template.cpp ├── list.cpp └── list.h /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-2017 SummerGift <459994202@qq.com> 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | 'Software'), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Lectures/Lecture-1.1-数据结构与算法.md: -------------------------------------------------------------------------------- 1 | # 引论 2 | 3 | ## 1. 数据结构与算法分析讨论的内容 4 | 5 | ## 2. 数学知识复习 6 | 7 | ## 3. 递归简论 8 | 9 | 关于递归问题的学习与思考写在专题学习的 [递归的思想与应用](./Project1-递归的思想与应用.md) 章节。 -------------------------------------------------------------------------------- /Lectures/Lecture-1.2-递归的思想与应用.md: -------------------------------------------------------------------------------- 1 | # 递归的思想与应用 2 | 3 | - [递归代码示例](../eclipse/DataStructuresCode/src/Project_01_recursive_function.cpp) 4 | 5 | ## 1 递归是数学上分而治之的思想 6 | 7 | - 将原问题分解为规模较小的问题进行处理 8 | - 分解后的问题与原问题类型完全相同,但规模较小 9 | - 通过小规模问题的解,能够轻易求得原问题的解 10 | - 问题的分解是有限的(递归不能无限进行) 11 | - 当边界条件不满足时,分解问题(递归继续进行) 12 | - 当边界条件满足时,直接求解(递归结束) 13 | 14 | ### 1.1 递归模型的一般表示方法 15 | 16 | ![1525163251581](assets/1525163251581.png) 17 | 18 | 19 | ## 2 递归在程序设计中的应用 20 | 21 | - 递归函数 22 | - 函数体中存在自我调用的函数 23 | - 递归函数`必须有递归出口`(base case 基准情况),在 c 的递归函数中若无基准情况是毫无意义的,因为递归调用将重复进行直到基准情形出现。 24 | - 函数的`无限递归将导致程序崩溃` 25 | - 在设计递归程序时,同一问题的所有较小的实例均可以假设运行正确,递归程序只需要把这些较小问题的解(他们通过递归奇迹般地得到)结合起来而形成现行问题的解。其数学依据是`归纳法`。 26 | - 递归的基本法则 27 | - 基准情形(base case)。你必须要有某些基准的情形,他们不用递归就能求解。 28 | - 不断推进(making progress)。对于那些需要递归求解的情形,递归调用必须能够朝着产生基准情形的方向推进。 29 | - 设计法则。假设所有的递归调用都能运行。 30 | - 合成效益法则(compond interest rule) 。在求解一个问题的同一实例时,切勿在不同的递归调用中做重复性的工作。这一条可以通过求斐波那契数量列的递归程序说明。可以查看 2.2 章节,当传入的 `index >= 3` 时,会执行如下的操作 `fac(n - 1) + fac(n - 2);`,而当调用 `fac(n - 1)`时其实已经计算了后面要用到的 `fac(n - 2) `,但是这里却没有使用已经计算了一次的结果,造成了大量重复运算,导致程序效率低下。 31 | 32 | ### 2.1 递归求和 33 | 34 | ![1525163382095](assets/1525163382095.png) 35 | 36 | - 代码实现: 37 | 38 | ```c 39 | unsigned int sum(int n) { 40 | if (n > 1) 41 | return n + sum(n - 1); 42 | else if (n == 1) { 43 | return 1; 44 | } 45 | } 46 | ``` 47 | 48 | ### 2.2 斐波那契数列 49 | 50 | ![1525163413002](assets/1525163413002.png) 51 | 52 | - 代码实现: 53 | 54 | ```c 55 | unsigned int fac(int n) { 56 | if (n >= 3) { 57 | return fac(n - 1) + fac(n - 2); 58 | } 59 | 60 | if (n == 2) 61 | return 1; 62 | 63 | if (n == 1) 64 | return 1; 65 | } 66 | ``` 67 | ### 2.3 用递归的方法编写函数求字符串长度 68 | 69 | ![1525163475986](assets/1525163475986.png) 70 | 71 | - 代码实现: 72 | 73 | ```c 74 | unsigned int get_strlen(char *s) { 75 | if (*s != '\0') 76 | return 1 + get_strlen(s + 1); 77 | if (*s == '\0') 78 | return 0; 79 | } 80 | ``` 81 | ### 2.4 单向链表的转置 82 | 83 | ![1525184315854](assets/1525184315854.png) 84 | 85 | - 代码实现: 86 | 87 | ```c 88 | List reverse(List list) { 89 | if ((list == NULL || list->Next == NULL)) { 90 | return list; 91 | } else { 92 | List guard = list->Next; 93 | List ret = reverse(list->Next); 94 | guard->Next = list; 95 | list->Next = NULL; 96 | return ret; 97 | } 98 | } 99 | ``` 100 | 101 | ### 2.5 单向排序链表的合并 102 | 103 | ![1525184468714](assets/1525184468714.png) 104 | 105 | - 代码实现: 106 | 107 | ```c 108 | List List_Merge(List L1, List L2) { 109 | if (L1 == NULL) { 110 | return L2; 111 | } else if (L2 == NULL) { 112 | return L1; 113 | } else if (L1->Data <= L2->Data) { 114 | List list_1 = L1->Next; 115 | List list = List_Merge(list_1, L2); 116 | L1->Next = list; 117 | return L1; 118 | } else { 119 | List list_2 = L2->Next; 120 | List list = List_Merge(list_2, L1); 121 | L2->Next = list; 122 | return L2; 123 | } 124 | } 125 | ``` 126 | 127 | ### 2.6 汉诺塔问题 128 | 129 | ![1525436823759](assets/1525436823759.png) 130 | 131 | ![1525436858718](assets/1525436858718.png) 132 | 133 | - 代码实现: 134 | 135 | ```c 136 | //汉诺塔问题:从 a 到 c, b 为中转站 137 | void HanoiTower(int n, char a, char b, char c) { 138 | if (n == 1) { 139 | cout << a << "-->" << c << endl; 140 | } else { 141 | HanoiTower(n - 1, a, c, b); 142 | HanoiTower(1, a, b, c); 143 | HanoiTower(n - 1, b, a, c); 144 | } 145 | } 146 | ``` 147 | 148 | ### 2.7 全排列问题 149 | 150 | ![1525441443912](assets/1525441443912.png) 151 | 152 | - 代码实现: 153 | 154 | ```c 155 | void permutation(char *s, char *e) { 156 | if (*s == '\0') { 157 | cout << e << endl; 158 | } else { 159 | int len = strlen(s); 160 | 161 | for (int i = 0; i < len; i++) { 162 | if ((i == 0) || (s[0] != s[i])) { 163 | swap(s[0], s[i]); 164 | permutation(s + 1, e); 165 | swap(s[0], s[i]); 166 | } 167 | } 168 | } 169 | } 170 | ``` 171 | 172 | ### 2.8 逆序打印单链表中的偶数结点 173 | #### 2.8.1 函数的调用过程回顾 174 | - 程序运行后有一个特殊的内存区供函数调用使用 175 | - 用于保存函数中的实参,局部变量,临时变量等 176 | - 从起始地址开始往一个方向增长(如:高地址 -> 低地址) 177 | - 有一个专用的指针标识当前已经使用的内存的“顶部”,及栈顶指针 178 | - 对函数栈使用的思考 179 | - 随着内存的使用或者释放,指针向下或者向上移动 180 | - 与特定函数调用相关的数据都存在各自函数的栈中,当 g() 函数返回,空间被释放后回到 f() 所在的栈,这个时候 f() 函数的栈数据没有变化。因此我们可以利用函数栈保存信息的特性来逆序递归的解决下面的问题。 181 | - 回溯算法的本质就是在栈上面作标记,以便于回退的时候使用。 182 | 183 | ![1525596336625](assets/1525596336625.png) 184 | 185 | #### 2.8.2 逆序打印单链表分析 186 | 187 | ![1525596423323](assets/1525596423323.png) 188 | 189 | - 题目分析 190 | 191 | - 递归出口是当 list 指向空的时候,函数直接返回 192 | - 当 list 不为空的时候递归调用反转打印函数,打印 list->next 的逆序,逐步减小问题规模 193 | - 当最终 list == NULL 的时候开始返回,利用栈中存储的信息来一步一步打印出链表中元素的值 194 | 195 | - 代码实现: 196 | ```c 197 | void list_attach(int data,List *pRear) { 198 | List P; 199 | 200 | P = (List) malloc(sizeof(struct Node)); 201 | P->Data = data; 202 | P->Next = NULL; 203 | 204 | (*pRear)->Next = P; //让尾节点的指针指向新的节点 205 | *pRear = P; //更新尾指针指向的位置 206 | } 207 | 208 | List create_list(int n) { 209 | 210 | List P, Rear, t; 211 | 212 | P = (List) malloc(sizeof(struct Node)); 213 | P->Next = NULL; 214 | Rear = P; 215 | 216 | for (int i = 0; i < n; i++) { 217 | list_attach(i, &Rear); 218 | } 219 | 220 | t = P; 221 | P = P->Next; 222 | free(t); 223 | 224 | return P; 225 | } 226 | 227 | //递归实现的反向输出链表中的偶数 228 | void r_print_even(List list) { 229 | if (list != NULL) { 230 | r_print_even(list->Next); 231 | 232 | if ((list->Data % 2) == 0) { 233 | cout << list->Data << endl; 234 | } 235 | } 236 | } 237 | ``` 238 | 239 | ### 2.9 八皇后问题 240 | 241 | ![1525602421047](assets/1525602421047.png) 242 | 243 | - 题目分析 244 | 245 | - 代码实现: 246 | ```c 247 | #include 248 | using namespace std; 249 | static int g_chessboard[8] = { 0 }, gCount = 0; 250 | 251 | void print() //输出每一种情况下棋盘中皇后的摆放情况 252 | { 253 | for (int i = 0; i < 8; i++) { 254 | int inner; 255 | for (inner = 0; inner < g_chessboard[i]; inner++) 256 | cout << "0"; 257 | cout << "#"; 258 | for (inner = g_chessboard[i] + 1; inner < 8; inner++) 259 | cout << "0"; 260 | cout << endl; 261 | } 262 | cout << "==========================\n"; 263 | } 264 | 265 | int check_pos_valid(int loop, int value) //检查是否存在有多个皇后在同一行/列/对角线的情况 266 | { 267 | int index; 268 | int data; 269 | for (index = 0; index < loop; index++) { 270 | data = g_chessboard[index]; 271 | if (value == data) 272 | return 0; 273 | if ((index + data) == (loop + value)) 274 | return 0; 275 | if ((index - data) == (loop - value)) 276 | return 0; 277 | } 278 | return 1; 279 | } 280 | 281 | void eight_queen(int index) { 282 | int loop; 283 | for (loop = 0; loop < 8; loop++) { 284 | if (check_pos_valid(index, loop)) { 285 | g_chessboard[index] = loop; 286 | if (7 == index) { 287 | gCount++, print(); 288 | g_chessboard[index] = 0; 289 | return; 290 | } 291 | eight_queen(index + 1); 292 | g_chessboard[index] = 0; 293 | } 294 | } 295 | } 296 | 297 | int main(int argc, char*argv[]) { 298 | eight_queen(0); 299 | cout << "total=" << gCount << endl; 300 | return 0; 301 | } 302 | ``` 303 | 304 | - 小结 305 | - 程序运行后的`栈存储区`专供函数调用使用 306 | - 栈存储区用于保存实参,局部变量,临时变量,寄存器等函数调用信息 307 | - 利用栈存储区能够方便的实现回溯算法 308 | - 八皇后问题是栈回溯的经典应用,仔细思考八皇后问题可以了解回溯算法的设计 309 | 310 | ## 3 总结 311 | 312 | - 递归是一种将问题`分而治之`的思想 313 | - 用递归解决问题`首先要建立递归的模型` 314 | - 递归解法`必须要有边界条件,否则无解` 315 | - `不要陷入递归函数的执行细节`,学会通过代码描述递归问题,我们需要了解的是递归函数背后的递归模型,只要掌握了递归模型,递归函数仅仅是递归模型的描述而已。 316 | 317 | -------------------------------------------------------------------------------- /Lectures/Lecture-2.1-抽象数据类型ADT.md: -------------------------------------------------------------------------------- 1 | # 抽象数据类型AD 2 | 3 | ## 内存分配 4 | 5 | 所有的 ADT 都必须确定一件事情那就是如何获取内存来储值。有三种可选的方案,静态数组、动态分配的数组和动态分配的链式结构。 6 | 7 | - 静态数组:要求结构的长度固定,而且这个长度必须在编译时确定。 8 | - 动态数组:可以在运行时才决定数组的长度,增加了数组的复杂性。 9 | - 链式结构:提供了最大程度的灵活性,但是链接字段需要消耗一定的内存。 10 | 11 | -------------------------------------------------------------------------------- /Lectures/Lecture-2.2-表ADT.md: -------------------------------------------------------------------------------- 1 | # 线性表的概念及实现 2 | 3 | ## 什么是抽象的链表 4 | 5 | - 有块地方存数据 6 | 7 | - 有块地方存指针——下一个节点的地址 8 | 9 | - 不一定是只有 C/C++ 这种有指针概念的语言才有链表,只要是数据以这种结构来存储,就是一个抽象的链表。比如说使用一个结构数组来实现一个链表。 10 | 11 | ![1524361788727](assets/1524361788727.png) 12 | 13 | -------------------------------------------------------------------------------- /Lectures/Lecture-2.3-堆栈ADT.md: -------------------------------------------------------------------------------- 1 | # 堆栈ADT 2 | 3 | ## 基础知识 4 | 5 | 堆栈: 6 | 7 | 具有一定操作约束的线性表,只在一端(栈顶)做插入、删除。 8 | 9 | 插入数据:入栈 10 | 删除数据:出栈 11 | 12 | 后入先出 LIFO 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 | 递推会比递归难这个问题,再思考思考也许就有答案了。 -------------------------------------------------------------------------------- /Lectures/Lecture-2.4-队列ADT.md: -------------------------------------------------------------------------------- 1 | # 队列ADT 2 | 3 | 队列: 4 | 具有一定操作约束的线性表,插入和删除操作,只能在一端插入,而在另一端删除。 5 | 数据插入: 入队队列 6 | 数据删除:出队列 7 | 先来先服务 8 | 先进先出 FIFO 9 | 10 | 循环队列 -------------------------------------------------------------------------------- /Lectures/Lecture-2.5-通用链表的实现.md: -------------------------------------------------------------------------------- 1 | # 通用链表的实现 2 | 3 | ## 基础知识 4 | 5 | - 链表是非常基本的数据结构,根据链的个数分为单链表、双链表,根据是否循环分为单向链表和循环链表。 6 | - 在操作系统的数据结构定义中,都看到了通用链表的定义。 7 | 8 | -------------------------------------------------------------------------------- /Lectures/Lecture-3.1-树的预备知识.md: -------------------------------------------------------------------------------- 1 | # 树的预备知识 2 | 3 | 分层次组织在管理上有更高的效率。 4 | 5 | 对于同一棵树而言,它的高度和深度是同一概念,但是对树上的结点来说,是不同的概念,因为同一节点的高度和深度可能不同。深度是从树根到这个结点的边的条数,高度是这个结点到下面叶节点的边条数的最大值。 6 | 7 | 数据管理的基本操作之一:查找 8 | 9 | 查找:根据某个给定的关键字k,从集合R中找出关键字与K相同的记录 10 | 11 | - 静态查找:集合中的记录是固定的 12 | 没有插入和删除操作 13 | 14 | - 动态查找:集合中的记录是动态变化的 15 | 除了查找,还可能发生插入和删除 16 | 17 | ## 静态查找 18 | 19 | - 方法一:顺序查找 20 | 21 | ```c 22 | /*在表Tbl[1]~Tbl[n]中查找关键字为K的数据元素*/ 23 | int SequentialSearch(StaticTable *Tbl, ElementType K) { 24 | int i; 25 | Tbl->Element[0] = K; /*建立哨兵*/ 26 | for (i = Tbl->Length; Tbl->Element[i] != K; i--) 27 | ; 28 | return i; /*查找成功返回所在单元下标;不成功返回0*/ 29 | } 30 | ``` 31 | 32 | 使用哨兵的好处是可以提高函数的性能,原因是不必在循环中判断数组是否越界。 33 | 34 | 顺序查找算法的时间复杂度为O(n)。 35 | 36 | - 方法二:二分查找 37 | 38 | ```c 39 | int BinarySearch(StaticTable * Tbl, ElementType K) { /*在表Tbl中查找关键字为K的数据元素*/ 40 | int left, right, mid, NoFound = -1; 41 | left = 1; 42 | right = Tbl->Length; 43 | while (left <= right) { 44 | mid = (left + right) / 2; /*计算中间元素坐标*/ 45 | if( K < Tbl->Element[mid]) 46 | } 47 | return NotFound; 48 | } 49 | ``` 50 | 51 | 二分查找的时间复杂度为 O(logN),如果查找的个数为偶数,(left + right) /2 向下取整即可。 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /Lectures/Lecture-3.2-二叉树.md: -------------------------------------------------------------------------------- 1 | # 二叉树及存储结构 2 | 3 | ## 二叉树的定义 4 | 5 | - 二叉树:一个有穷的结点集合 6 | 这个集合可以为空。 7 | 若不为空,则它是由**根节点**和称为其**左子树**和**右子树**的两个不相交的二叉树组成。 8 | 9 | ### 特殊二叉树: 10 | - 斜二叉树 11 | - 完美二叉树(满二叉树) 12 | - 完全二叉树 13 | 有 n 个结点的二叉树,对树中结点按 从上至下、从左到右顺序进行编号, 编号为 $i(1 ≤ i ≤ n)$ 结点与满二叉树 中编号为 $i$ 结点在二叉树中位置相同。 14 | 15 | ## 二叉树的几个重要性质 16 | 17 | - 一个二叉树第 $i$ 层的最大结点数为: $2^{ i-1}$,i $\ge$ 1。 18 | - 深度为 $k$ 的二叉树有最大结点总数为: $2^{k}$,k $\ge$ 1。 19 | - 对任何非空二叉树 $T$,若 $n_0$ 表示叶结点的个数、$n_2$ 是度为 2 的非叶结点个数,那么两者满足关系 $n_0$ = $n_2$ +1。 20 | 21 | ## 二叉树的抽象数据类型定义 22 | 23 | 类型名称: 二叉树 24 | 数据对象集:一个有穷的结点集合。 若不为空,则由根结点和其左、右二叉子树组成。 25 | 操作集: BT $\in\ $BinTree, Item $\in\ $ElementType,重要操作有: 26 | 1、Boolean IsEmpty( BinTree BT ): 判别 BT 是否为空; 27 | 2、void Traversal( BinTree BT ):遍历,按某顺序访问每 个结点; 28 | 3、BinTree CreatBinTree( ):创建一个二叉树。 29 | 30 | ## 二叉树的存储结构 31 | 32 | ### 顺序存储结构 33 | 34 | - 完全二叉树:按从上至下、从左到右顺序存储 n个结点的完全二叉树的结点父子关系: 35 | 非根结点(序号 $ i > 1$)的父结点的序号是 $ i / 2$; 36 | 结点(序号为 $i$ )的左孩子结点的序号是 $2i$,(若$2 i <= n$,否则没有左孩子); 37 | 结点(序号为 $i$ )的右孩子结点的序号是 $2i+1$, (若$2 i +1<= n$,否则没有右孩子); 38 | - 一般二叉树也可以按照完全二叉树的方式来存储,但是会造成空间浪费。 39 | 40 | ### 链表存储 41 | 42 | ```c 43 | typedef struct TreeNode *BinTree; 44 | typedef BinTree Position; 45 | struct TreeNode { 46 | ElementType Data; 47 | BinTree Left; 48 | BinTree Right; 49 | } 50 | ``` 51 | 52 | # Lecture-7 二叉树的遍历 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 | - 在上述过程中如果遇到叶节点,直接存入到另外一个队列中,循环结束后,返回依次存放了叶节点的队列,依次输出即可获得层序遍历顺序的叶节点。 -------------------------------------------------------------------------------- /Lectures/Lecture-3.3-查找树ADT(二叉查找树).md: -------------------------------------------------------------------------------- 1 | # 查找树ADT 2 | 3 | 二叉搜索树(BST,Binary Search Tree),也称二叉排序树或二叉查找树。 4 | 二叉搜索树:一棵二叉树,可以为空;如果不为空,满足以下性质: 5 | 1. 非空左子树的所有键值小于其根结点的键值。 6 | 2. 非空右子树的所有键值大于其根结点的键值。 7 | 3. 左、右子树都是二叉搜索树。 8 | 4. 这意味着该树所有的元素可以用某种统一的方式排序。 9 | 10 | ## 二叉搜索树的查找操作:Find 11 | 12 | - 查找从根结点开始,如果树为空,返回 NULL 13 | 14 | - 若搜索树非空,则根结点关键字和 X 进行比较,并进行不同处理: 15 | 1.若X小于根结点键值,只需在左子树中继续搜索; 16 | 2.如果X大于根结点的键值,在右子树中进行继续搜索; 17 | 3.若两者比较结果是相等,搜索完成,返回指向此结点的指针。 18 | 19 | 20 | ![1523856492024](assets/1523856492024.png) 21 | 22 | - 由于非递归函数的执行效率高,可将“尾递归”函数改为迭代函数。 23 | 24 | ![1523856765127](assets/1523856765127.png) 25 | 26 | ### 查找最大和最小元素 27 | 28 | - 最大元素一定是在树的最右分枝的端结点上 29 | - 最小元素一定是在树的最左分枝的端结点上 30 | 31 | 32 | ## 二叉搜索树的插入 33 | 34 | ## 二叉搜索树的删除 35 | 36 | - 是否是同一棵二叉搜索树,两个序列是否对应相同搜索树的判别 -------------------------------------------------------------------------------- /Lectures/Lecture-3.4-AVL树.md: -------------------------------------------------------------------------------- 1 | # 平衡二叉树 2 | 3 | ## 什么是平衡二叉树 4 | 5 | - “平衡因子”: BF(T) = $h_L$ - $h_R$ ,其中 $h_L$ 和 $h_R$ 分别为 T 的左右子树的高度。 6 | - 平衡二叉树(AVL 树): 7 | - 空树 8 | - 任意节点左、右子树高度差的绝对值不超过1,即 |BF(T)|≤ 1。 9 | - 给定节点数为 n 的 AVL 树的最大高度为是 $O(\log_2 n) $ 。 10 | 11 | 12 | ## 平衡二叉树的调整 13 | 14 | 如果新插入的数据破坏了原有二叉树的平衡,就需要调整二叉树的结构,使之重新平衡。 15 | 16 | - RR 17 | - LL 18 | - LR 19 | - RL -------------------------------------------------------------------------------- /Lectures/Lecture-4.1-堆.md: -------------------------------------------------------------------------------- 1 | # 优先队列(堆) 2 | 3 | - 优先队列:特殊的**队列**,取出元素的顺序是依照元素的优先权(关键字)大小,而不是元素进入队列的先后顺序。 4 | 5 | ## 实现方式 6 | 7 | - 若采用数组或链表实现优先队列 8 | - 是否可以使用使用二叉树存储结构 9 | - 使用完全二叉树进行存储,效率会比较高 10 | 11 | 堆的两个特性: 12 | - 结构性:用数组表示的完全二叉树 13 | - 有序性:任一结点的关键字是其子树所有结点的最大值(或最小值) 14 | 15 | 类型名称:最大堆 16 | 数据对象集:完全二叉树,每个结点的元素值不小于其子节点的元素值 17 | 操作集 主要操作: 18 | - 创建一个空的最大堆 19 | - 判断最大堆H是否已满 20 | - 将元素item插入最大堆 21 | - 判断最大堆H是否为空 22 | - 返回H中最大元素(高优先级) 23 | 24 | 使用数组来存放完全二叉树,在下标为0的位置上不存放元素,就可以做到根节点下标为n,那么的左儿子的下标为2n,由儿子的下标为2n+1。 25 | 26 | ## 最大堆的建立 27 | 28 | - 建立最大堆:将已经存在的 N 个元素按最大堆的要求存放在一个一维数组中。 -------------------------------------------------------------------------------- /Lectures/Lecture-4.2-哈夫曼树与哈夫曼编码.md: -------------------------------------------------------------------------------- 1 | # 哈夫曼树与哈夫曼编码 2 | 3 | ## 基础知识 4 | 5 | - 标准的 ASCII 字符集由大约100个可打印字符组成。为了把这些字符区分开来,需要 log^100 = 7个比特。但是7个比特可以表示128个字符,因此ASCII字符还可以再加上一些其他的非打印字符。我们加上第8个比特位作为奇偶校验位。不过重要的问题在于,如果字符集的大小是C,那么在标准的编码中就需要 log^C 个比特。 6 | 7 | - 在现实中,文件可能是相当大的,许多非常大的文件是某个程序的输出数据,而在使用频率最大和最小字符之间通常存在很大的差别。那么能否有一种更好的编码降低总的所需的比特数。 8 | 9 | - 答案是肯定的,一种简单的策略可以使一般的大型文件节省25%,而使许多大型的数据文件节省多达 50%~60%。这种一般的策略就是让代码的长度从字符到字符是变化不等的,同时保证经常出现的字符其代码短。注意,如果所有的字符都以相同的,那么要节省空间是不可能的。 10 | 11 | - 满树:所有的结点或者是树叶,或者是树叶,或者有两个儿子。一种最优的编码将总具有这个性质,否则具有一个儿子的结点可以向上移动一层。 12 | 13 | - 如果字符都只放在树叶上,那么任何比特序列总能够被毫无歧义地译码。这些字符编码的长度是否不同并不要紧,只要没有字符代码是别的字符代码的前缀即可。这种编码叫做前缀码(character code)。相反,如果一个字符放在非树叶结点上,那就不再能够保证译码没有二义性。 14 | 15 | - 所以基本问题在于找到总价值最小的满二叉树,其中所有的字符都位于树叶上。 16 | 17 | ## 哈夫曼算法 18 | 19 | - 假设字符的个数为C,那么哈夫曼算法可以描述如下:算法对一个由树组成的森林进行。一棵树的权等于他的树叶的频率的和。任意选取最小权的两棵树 T1 和 T2 ,并任意形成以 T1 和 T2 为子树的新数,将这样的过程进行 C-1 次。在算法的开始,存在C棵单节点树——每个字符一棵。在算法结束时得到一棵树,这棵树就是最优哈夫曼树。 20 | - 哈夫曼编码不唯一。 21 | - 根据哈夫曼算法得到的一定是最优编码,但是最优编码不一定通过哈夫曼算法得到。 22 | 23 | ## 哈夫曼编码的特点 24 | 25 | - 最优编码——总长度(WPL) 最小 26 | - 无歧义解码——前缀码:数据仅存于叶子节点 -------------------------------------------------------------------------------- /Lectures/Lecture-4.3-不相交集ADT.md: -------------------------------------------------------------------------------- 1 | # 不相交集 ADT 2 | 3 | ## 基础知识 4 | 5 | - 链表是非常基本的数据结构,根据链的个数分为单链表、双链表,根据是否循环分为单向链表和循环链表。 -------------------------------------------------------------------------------- /Lectures/Lecture-6.1-排序.md: -------------------------------------------------------------------------------- 1 | # 排序 2 | 3 | ## 前提 4 | 5 | - 大多情况下,为简单起见,讨论从小到大的整数排序 6 | - 数据个数N是正整数 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 | -------------------------------------------------------------------------------- /Lectures/assets/1523856492024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SummerGift/DataStructure/1103b05bc34be926fa734f05415bd52cfa5f733c/Lectures/assets/1523856492024.png -------------------------------------------------------------------------------- /Lectures/assets/1523856765127.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SummerGift/DataStructure/1103b05bc34be926fa734f05415bd52cfa5f733c/Lectures/assets/1523856765127.png -------------------------------------------------------------------------------- /Lectures/assets/1524361788727.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SummerGift/DataStructure/1103b05bc34be926fa734f05415bd52cfa5f733c/Lectures/assets/1524361788727.png -------------------------------------------------------------------------------- /Lectures/assets/1525163251581.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SummerGift/DataStructure/1103b05bc34be926fa734f05415bd52cfa5f733c/Lectures/assets/1525163251581.png -------------------------------------------------------------------------------- /Lectures/assets/1525163382095.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SummerGift/DataStructure/1103b05bc34be926fa734f05415bd52cfa5f733c/Lectures/assets/1525163382095.png -------------------------------------------------------------------------------- /Lectures/assets/1525163413002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SummerGift/DataStructure/1103b05bc34be926fa734f05415bd52cfa5f733c/Lectures/assets/1525163413002.png -------------------------------------------------------------------------------- /Lectures/assets/1525163442489.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SummerGift/DataStructure/1103b05bc34be926fa734f05415bd52cfa5f733c/Lectures/assets/1525163442489.png -------------------------------------------------------------------------------- /Lectures/assets/1525163475986.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SummerGift/DataStructure/1103b05bc34be926fa734f05415bd52cfa5f733c/Lectures/assets/1525163475986.png -------------------------------------------------------------------------------- /Lectures/assets/1525184315854.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SummerGift/DataStructure/1103b05bc34be926fa734f05415bd52cfa5f733c/Lectures/assets/1525184315854.png -------------------------------------------------------------------------------- /Lectures/assets/1525184468714.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SummerGift/DataStructure/1103b05bc34be926fa734f05415bd52cfa5f733c/Lectures/assets/1525184468714.png -------------------------------------------------------------------------------- /Lectures/assets/1525436823759.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SummerGift/DataStructure/1103b05bc34be926fa734f05415bd52cfa5f733c/Lectures/assets/1525436823759.png -------------------------------------------------------------------------------- /Lectures/assets/1525436858718.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SummerGift/DataStructure/1103b05bc34be926fa734f05415bd52cfa5f733c/Lectures/assets/1525436858718.png -------------------------------------------------------------------------------- /Lectures/assets/1525441443912.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SummerGift/DataStructure/1103b05bc34be926fa734f05415bd52cfa5f733c/Lectures/assets/1525441443912.png -------------------------------------------------------------------------------- /Lectures/assets/1525596336625.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SummerGift/DataStructure/1103b05bc34be926fa734f05415bd52cfa5f733c/Lectures/assets/1525596336625.png -------------------------------------------------------------------------------- /Lectures/assets/1525596423323.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SummerGift/DataStructure/1103b05bc34be926fa734f05415bd52cfa5f733c/Lectures/assets/1525596423323.png -------------------------------------------------------------------------------- /Lectures/assets/1525602421047.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SummerGift/DataStructure/1103b05bc34be926fa734f05415bd52cfa5f733c/Lectures/assets/1525602421047.png -------------------------------------------------------------------------------- /Lectures/rt-thread/1-内核对象模型.md: -------------------------------------------------------------------------------- 1 | ## RT-Thread 内核对象模型 2 | 3 | 在 RT-Thread 的内核对象模型是一种非常有趣的面向对象实现方式。面向对象由它非常优越的地方,我们应当取其精髓(即面向对象的思想,面向对象设计),也就是 RT-Thread 内核对象模型的来源。RT-Thread 实时操作系统中包含一个小型的,非常紧凑的对象系统,这个对象系统完全采用 C 语言实现。在了解 RT-Thread 内部或采用 RT-Thread 编程时有必要先熟悉他,它是 RT-Thread 实现的基础。 4 | 5 | ### C语言的对象化模型 6 | 7 | 面向对象的特征主要包括: 8 | 9 | - 封装,隐藏内部实现 10 | - 继承,复用现有代码 11 | - 多态,改写对象行为 12 | 13 | 采用 C 语言实现的关键是如何运用 C 语言本身的特性来实现上述面向对象的特征。 14 | 15 | #### 封装 #### 16 | 17 | 封装是一种信息隐蔽技术,它体现于类的说明,是对象的重要特性。封装使数据和加工该数据的方法(函数)封装为一个整体,以实现独立性很强的模块,使得用户只能见到对象的外特性(对象能接受哪些消息,具有那些处理能力),而对象的内特性(保存内部状态的私有数据和实现加工能力的算法)对用户是隐蔽的。封装的目的在于把对象的设计者和使用者分开,使用者不必知晓行为实现的细节,只须用设计者提供的消息来访问该对象。这就像开车一样,并不需要知道车子的制造方法,只需要知道怎么操作即可,而我们也知道,汽车的有些核心技术对用户是保密的,这就是一种“屏蔽”。 18 | 19 | 在 C 语言中,大多数函数的命名方式是“动词名词”的形式,例如要获取一个 semaphore,会命名成 take_semaphore,重点在 take 这个动作上。在 RT-Thread 系统的面向对象编程中刚好相反,命名为 rt_sem_take,即“名词动词”的形式,重点在名词上,即这个对象,它体现了该对象的一种方法。另外对于某些方法,由于其仅局限在对象内部使用,因此可采用 static 关键词把它们的作用范围局限在一个文件的内部。通过这样的方式,就能把一些不想让用户知道的信息屏蔽在封装里,用户只能看到外层的接口,从而形成了面向对象的最基本的对象封装实现。 20 | 21 | 一般属于某个类的对象会有一个统一的创建,称之为构造过程。在 RT-Thread 中这些对象分为两类(以 semaphore 对象为例): 22 | 23 | - 对象内存数据块已经存在,需要对它进行初始化 – rt_sem_init; 24 | - 对象内存数据块还未分配,需要创建并初始化 – rt_sem_create. 25 | 26 | 可以这么认为,对象的创建(create)是以对象的初始化(init)为基础,相对来说创建动作多了一个内存分配的行为。 27 | 28 | 相对应的两类析构方式: 29 | 30 | - 由 rt_sem_init 初始化的 semaphore 对象 – rt_sem_detach; 31 | - 由 rt_sem_create 创建的 semaphore 对象 – rt_sem_delete. 32 | 33 | #### 继承 #### 34 | 35 | 继承性是指子类自动共享父类的数据和方法的机制。它由类的派生功能体现。一个类直接继承类的其它全部描述,同时可修改和扩充。继承具有传递性,继承分为单继承(一个子类只有一父类)和多重继承(一个类有多个平行的父类,当前 RT-Thread 的对象系统不能支持)。类的对象是各自封闭的,如果没继承性机制,则类对象中数据、方法就会出现大量重复。继承不仅支持系统的可重用性,而且还促进系统的可扩充性。 36 | 37 | 类的实现代码如下: 38 | 39 | ```{.c} 40 | /* 父类 */ 41 | struct parent_class 42 | { 43 | int a, b; 44 | char *str; 45 | }; 46 | 47 | /* 继承于父类的子类 */ 48 | struct child_class 49 | { 50 | struct parent_class p; 51 | int a, b; 52 | }; 53 | 54 | /* 操作示例函数*/ 55 | void func() 56 | { 57 | struct child_class obj, *obj_ptr; /* 子类对象及指针 */ 58 | struct parent_class *parent_ptr; /* 父类指针 */ 59 | 60 | obj_ptr = &obj; 61 | /* 取父指针 */ 62 | ① parent_ptr = (struct parent_class*) &obj; 63 | 64 | /* 可通过转换过类型的父类指针访问相应的属性 */ 65 | parent_ptr->a = 1; 66 | parent_ptr->b = 5; 67 | 68 | /* 子类属性的操作 */ 69 | obj_ptr->a = 10; 70 | obj_ptr->b = 100; 71 | } 72 | ``` 73 | 74 | 在上面的例子中,注意 child_class 结构中第一个成员 p,这种声明方式代表 child_class 类型的数据中开始的位置包含一个 parent_class 类型的变量。在函数`func`中 obj 是一个 child_class 对象,正像这个结构类型指示的,它前面的数据应该包含一个 parent_class 类型的数据。在①处的强制类型赋值中 parent_ptr 指向了 obj 变量的首地址,也就是 obj 变量中的 p 对象。好了,现在 parent_ptr 指向的是一个真真实实的 parent 类型的结构,那么可以按照 parent 的方式访问其中的成员,当然也包括可以使用和 parent 结构相关的函数来处理内部数据,因为一个正常的,正确的代码,它是不会越界访问 parent 结构体以外的数据的。 75 | 76 | 经过这基本的结构体层层相套包含,对象简单的继存关系就体现出来了:父对象放于数据块的最前方,代码中可以通过强制类型转换获得父对象指针。 77 | 78 | #### 多态 #### 79 | 80 | 对象根据所接收的消息而做出动作,同一消息为不同的对象接受时,对象所产生的动作完全有可能不一样,而这种现象就被称之为多态性。利用多态性用户可发送一个通用的信息,而将所有的实现细节都留给接受消息的对象自行决定,如此一来,同一消息即可调用不同的方法。例如 RT-Thread 系统中的设备:那些抽象设备就具备统一的读写接口,而串口虽然也是设备的一种,也应支持设备的读写,但串口的读写操作是串口所特有的,和其他设备的操作并非完全相同,因此对串口设备的操作应该和抽象设备区别开来,例如串口操作不应应用于 SD 卡设备中。 81 | 82 | 多态性的实现受到继承性的支持,利用类继承的层次关系,应把具有通用功能的协议存放在类层次中尽可能高的地方,而将实现这一功能的不同方法置于较低层次,这样,在这些低层次上生成的对象就能给通用消息以不同的响应。 83 | 84 | 在 RT-Thread 对象模型中,采用结构封装的指针形式可实现面向对象的多态效果,如下例所示: 85 | 86 | ```{.c} 87 | #include 88 | 89 | /* 抽象父类 */ 90 | struct parent_class 91 | { 92 | int a; 93 | 94 | /* 反映不同类别属性的方法 */ 95 | void (*vfunc)(struct parent_class* self, int a); 96 | }; 97 | 98 | /* 抽象类的方法调用 */ 99 | void parent_class_vfunc(struct parent_class *self, int a) 100 | { 101 | RT_ASSERT(self != RT_NULL); 102 | RT_ASSERT(slef->vfunc != RT_NULL); 103 | 104 | /* 调用对象本身的虚拟函数 */ 105 | self->vfunc(self, a); 106 | } 107 | 108 | /* 抽象类的虚拟函数 */ 109 | static void _parent_vfunc(struct parent_class* self, int a) 110 | { 111 | RT_ASSERT(self != RT_NULL); 112 | self->a += a; 113 | 114 | /* 输出相应的信息 */ 115 | rt_kprintf("parent's a=%d\n", self->a); 116 | } 117 | 118 | /* 抽象类的构造函数 */ 119 | void parent_class_init(struct parent_class* self) 120 | { 121 | RT_ASSERT(self != RT_NULL); 122 | self->a = 1; 123 | self->vfunc = _parent_vfunc; 124 | } 125 | 126 | /* 继承自parent_class的子类 */ 127 | struct child_class 128 | { 129 | struct parent_class parent; 130 | int b; 131 | }; 132 | 133 | /* 子类的虚拟函数实现 */ 134 | static void _child_class_vfunc(struct parent_class* self, int a) 135 | { 136 | struct child_class *child = (struct child_class*)self; 137 | child->b = a + 10; 138 | 139 | /* 输出相应的信息 */ 140 | rt_kprintf("child's b=%d\n", child->b); 141 | } 142 | 143 | /* 子类的构造函数 */ 144 | void child_class_init(struct child_class* self) 145 | { 146 | struct parent_class* parent; 147 | 148 | /* 强制类型转换获得父类指针 */ 149 | parent = (struct parent_class*) self; 150 | RT_ASSERT(parent != RT_NULL); 151 | 152 | /* 设置子类的虚拟函数 */ 153 | parent->vfunc = _child_class_vfunc; 154 | } 155 | 156 | void obj_test() 157 | { 158 | struct parent_class *ptr; 159 | struct parent_class parent; 160 | struct child_class child; 161 | 162 | parent_class_init(&parent); 163 | child_class_init(&child); 164 | 165 | ptr = (struct parent_class *)&parent; 166 | parent_class_vfunc(ptr, 10); 167 | ptr = (struct parent_class *)&child; 168 | parent_class_vfunc(ptr, 10); 169 | } 170 | ``` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Readme 2 | 3 | ## About this repo 4 | 5 | - This repo consists of my notes of datastructures classes taught in University of ZHEJIANG on MOOC. 6 | - Most of the code that this branch contains will be written by C/C++. 7 | - Record C/C++ data structure exercises. 8 | - Summarize the learning content and put forward my own understanding. 9 | ___ 10 | 11 | 单纯的学习数据结构本身是不够的,结合工作中实际工作项目来实践才能所学的知识融会贯通。因此我决定添加数据结构工作应用章节。在 RT-Thread 中用到了许多常用的数据结构,当我发现可以用通用双向链表来实现内核对象管理的时候,我在心底里感叹这种数据结构如此奇妙。通过阅读高质量的源码,可以提高学习效果,这是一种很棒的做法。看到一种数据结构的巧妙应用,回过头来再继续学习总结,我相信这个过程可以对提高自身的水平有很大帮助。 12 | 13 | 数据结构课程讲述的内容是比较全面的,除了基本的数据结构和算法的概念,算法复杂度的计算还有递归专题,抽象数据类型等。数据结构从基本的表、堆栈、队列、一直讲到较为复杂的树、图、散列表,另外讲述了一些常用的排序算法,并且在每一章之后都提供了足够多的练习题,为了写这些练习题真的是绞尽脑汁。 14 | 15 | 在我从事的嵌入式工作中,常用的数据结构有双向链表、动态数组、队列、堆、栈、散列表,常用的算法一般就是排序和查找。但我觉得像是树、图这样的数据结构还是要去学的,侯捷先生说过:“学从难处学,用从易处用”。在学习的过程中一定要精到不能再精为止。 16 | 17 | 数据结构和 C++ 的学习从建立工程开始提交练习代码到18年6月已经有半年时间了,说真的坚持真的不容易,即使中间有曲折,无论如何我已经下决心要把这件事做到底,把这项技能掌握好。无论需要学习几遍,不管到什么时候,这件事必须要有始有终,继续加油。 18 | 19 | ## Content 20 | 21 | ### 1. 学习总结 22 | #### 第一章:基本概念 23 | - [x] [Lecture 1.1 - 数据结构与算法](./Lectures/Lecture-1.1-数据结构与算法.md) 24 | - [x] [Lecture 1.2 - 递归的思想与应用](./Lectures/Lecture-1.2-递归的思想与应用.md) 25 | #### 第二章:表、栈和队列 26 | - [x] [Lecture 2.1 - 抽象数据类型 ADT](./Lectures/Lecture-2.1-抽象数据类型ADT.md) 27 | - [x] [Lecture 2.2 - 表 ADT](./Lectures/Lecture-2.2-表ADT.md) 28 | - [x] [Lecture 2.3 - 堆栈 ADT](./Lectures/Lecture-2.3-堆栈ADT.md) 29 | - [ ] [Lecture 2.4 - 队列 ADT](./Lectures/Lecture-2.4-队列ADT.md) 30 | - [x] [Lecture 2.5 - 通用链表的实现](./Lectures/Lecture-2.5-通用链表的实现.md) 31 | #### 第三章:树 32 | - [x] [Lecture 3.1 - 树的预备知识](./Lectures/Lecture-3.1-树的预备知识.md) 33 | - [x] [Lecture 3.2 - 二叉树](./Lectures/Lecture-3.2-二叉树.md) 34 | - [x] [Lecture 3.3 - 查找树 ADT(二叉查找树)](./Lectures/Lecture-3.3-查找树ADT(二叉查找树).md) 35 | - [x] [Lecture 3.4 - AVL树](./Lectures/Lecture-3.4-AVL树.md) 36 | #### 第四章:优先队列(堆) 37 | - [x] [Lecture 4.1 - 堆](./Lectures/Lecture-4.1-堆.md) 38 | - [x] [Lecture 4.2 - 哈夫曼树与哈夫曼编码](./Lectures/Lecture-4.2-哈夫曼树与哈夫曼编码.md) 39 | - [ ] [Lecture 4.3 - 不相交集 ADT](./Lectures/Lecture-4.3-不相交集ADT.md) 40 | #### 第五章:图论算法 41 | - [ ] [Lecture 5.1 - 图](./Lectures/Lecture-4.1-堆.md) 42 | #### 第六章:排序 43 | - [x] [Lecture 6.1 - 排序](./Lectures/Lecture-6.1-排序.md) 44 | 45 | ### 2. 数据结构练习题 46 | 47 | #### 1. Complexity 48 | 49 | * 01-1 [Maxsubsequencesum question (C)](./eclipse/DataStructuresCode/src/01_1_Maxsubsequencesum_question.cpp) 50 | * 01-2 [Maximum Subsequence Sum (C)](./eclipse/DataStructuresCode/src/01_2_Maximum_Subsequence_Sum.cpp) 51 | * 01-3 [BinarySearch (C)](./eclipse/DataStructuresCode/src/01_3_BinarySearch.cpp) 52 | * 01-4 [RecursiveProject(C++)](./eclipse/DataStructuresCode/src/Project_01_recursive_function.cpp) 53 | 54 | #### 2. List 55 | 56 | * 02-1 [List Merge (C)](./eclipse/DataStructuresCode/src/02_1_List_Merge.cpp) 57 | * 02-2 [List mult add (C)](./eclipse/DataStructuresCode/src/02_2_list_mult_add.cpp) 58 | * 02-3 [Reversing Linked List (C)](./eclipse/DataStructuresCode/src/02_3_Reversing_Linked_List.cpp) 59 | * 02-4 [Pop Sequence (C++)](./eclipse/DataStructuresCode/src/02_4_Pop_Sequence.cpp) 60 | 61 | #### 3. Trees 62 | 63 | - 03-1 [Tree isomorphism (C)](./eclipse/DataStructuresCode/src/03_1_Tree_isomorphism.cpp) 64 | - 03-2 [List Leaves (C++)](./eclipse/DataStructuresCode/src/03_2_List_Leaves.cpp) 65 | - 03-3 [Tree Traversals Again (C)](./eclipse/DataStructuresCode/src/03_3_Tree_Traversals_Again.cpp) 66 | - 04-4 [Is Same BinarySearch Tree (C)](./eclipse/DataStructuresCode/src/04_4_IsSameBinarySearchTree.cpp) 67 | - 04-5 [Root of AVL_Tree (C)](./eclipse/DataStructuresCode/src/04_5_Root_of_AVL_Tree.cpp) 68 | - 04-6 [Complete Binary Search Tree (C)](./eclipse/DataStructuresCode/src/04_6_Complete_Binary_Search_Tree.cpp) 69 | - 04-7 [Binarysearch tree operation set (C)](./eclipse/DataStructuresCode/src/04_7_Binarysearch_tree_operation_set.cpp) 70 | - 05-7 [Heap Path (C)](./eclipse/DataStructuresCode/src/05_7_heap_path.cpp) 71 | - 05-8 [File Transfer (C)](./eclipse/DataStructuresCode/src/05_8_File_Transfer.cpp) 72 | - 05-9 [Huffman Codes (C)](./eclipse/DataStructuresCode/src/05_9_Huffman_Codes.cpp) 73 | 74 | ### 3. 数据结构工作应用 75 | 76 | 本章介绍在 RT-Thread 操作系统中所使用的数据结构,研究如何使用这些常见的数据结构来实现复杂的系统功能。 77 | 78 | - [x] [第一章:内核对象模型](./Lectures/rt-thread/1-内核对象模型.md) 79 | 80 | ## Note style 81 | 82 | ### Code 83 | 84 | All code will be marked \`\`\`Language ...code... \`\`\` when the lecture is read in raw format. When viewed through Github and Pandoc, it will be color coded based on the language as such: 85 | 86 | * C 87 | ```c 88 | #include 89 | int main(void){ 90 | char * foo = "bar"; 91 | printf("%s",foo); 92 | return 0; 93 | } 94 | ``` 95 | * All C code is Compiled with ```MinGW.org GCC-6.3.0-1```. 96 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/.cproject: -------------------------------------------------------------------------------- 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 | 55 | 56 | 57 | 58 | 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 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 147 | 148 | 149 | 150 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/.gitignore: -------------------------------------------------------------------------------- 1 | /Debug/ 2 | /Release/ 3 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | DataStructuresCode 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | 14 | 15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 16 | full,incremental, 17 | 18 | 19 | 20 | 21 | 22 | org.eclipse.cdt.core.cnature 23 | org.eclipse.cdt.core.ccnature 24 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 25 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 26 | 27 | 28 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/.settings/language.settings.xml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/.settings/org.eclipse.cdt.managedbuilder.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1227918974/CPATH/delimiter=; 3 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1227918974/CPATH/operation=remove 4 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1227918974/CPLUS_INCLUDE_PATH/delimiter=; 5 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1227918974/CPLUS_INCLUDE_PATH/operation=remove 6 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1227918974/C_INCLUDE_PATH/delimiter=; 7 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1227918974/C_INCLUDE_PATH/operation=remove 8 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1227918974/append=true 9 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1227918974/appendContributed=true 10 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.release.1151344238/CPATH/delimiter=; 11 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.release.1151344238/CPATH/operation=remove 12 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.release.1151344238/CPLUS_INCLUDE_PATH/delimiter=; 13 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.release.1151344238/CPLUS_INCLUDE_PATH/operation=remove 14 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.release.1151344238/C_INCLUDE_PATH/delimiter=; 15 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.release.1151344238/C_INCLUDE_PATH/operation=remove 16 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.release.1151344238/append=true 17 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.release.1151344238/appendContributed=true 18 | environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.1227918974/LIBRARY_PATH/delimiter=; 19 | environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.1227918974/LIBRARY_PATH/operation=remove 20 | environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.1227918974/append=true 21 | environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.1227918974/appendContributed=true 22 | environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.release.1151344238/LIBRARY_PATH/delimiter=; 23 | environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.release.1151344238/LIBRARY_PATH/operation=remove 24 | environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.release.1151344238/append=true 25 | environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.release.1151344238/appendContributed=true 26 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/02_3_Reversing_Linked_List.cpp=UTF-8 3 | encoding//src/03_1_Tree_isomorphism.cpp=UTF-8 4 | encoding//src/03_2_List_Leaves.cpp=UTF-8 5 | encoding//src/main.cpp=UTF-8 6 | encoding/=UTF-8 7 | encoding/src=UTF-8 8 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/01_1_Maxsubsequencesum_question.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Maxsubsequencesum_1.cpp 3 | * 4 | * Created on: 2018年4月7日 5 | * Author: Summer 6 | */ 7 | 8 | /* 9 | 01-复杂度1 最大子列和问题(20 分) 10 | 11 | 给定K个整数组成的序列{ N1, N2, ..., NK },“连续子列”被定义为{ Ni, Ni+1, ..., Nj }, 12 | 其中 1 <= i <= j <= K。“最大子列和”则被定义为所有连续子列元素的和中最大者。 13 | 例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。 14 | 现要求你编写程序,计算给定整数序列的最大子列和。 15 | 16 | 本题旨在测试各种不同的算法在各种数据情况下的表现。各组测试数据特点如下: 17 | 18 | 数据1:与样例等价,测试基本正确性; 19 | 数据2:102个随机整数; 20 | 数据3:103个随机整数; 21 | 数据4:104个随机整数; 22 | 数据5:105个随机整数; 23 | 输入格式: 24 | 25 | 输入第1行给出正整数K (≤100000);第2行给出K个整数,其间以空格分隔。 26 | 27 | 输出格式: 28 | 29 | 在一行中输出最大子列和。如果序列中所有整数皆为负数,则输出0。 30 | 31 | 输入样例: 32 | 33 | 6 34 | -2 11 -4 13 -5 -2 35 | 输出样例: 36 | 37 | 20 38 | 39 | */ 40 | 41 | #include 42 | 43 | static int MaxSubseqSum1(int A[], int N) 44 | { 45 | int ThisSum, MaxSum; 46 | int i; 47 | ThisSum = MaxSum = 0; 48 | for (i = 0; i < N; i++) 49 | { 50 | ThisSum += A[i]; /* 向右累加 */ 51 | if (ThisSum > MaxSum) 52 | MaxSum = ThisSum; /* 发现更大和则更新当前结果 */ 53 | else if (ThisSum < 0) /* 如果当前子列和为负 */ 54 | ThisSum = 0; /* 则不可能使后面的部分和增大,抛弃之 */ 55 | } 56 | return MaxSum; 57 | } 58 | 59 | // int main() 60 | //{ 61 | // int i, *a; 62 | // int arraycount; 63 | // int result; 64 | // scanf("%d",&arraycount); 65 | // 66 | // a = malloc(sizeof(int) * arraycount); /*分配内存*/ 67 | // 68 | // for(i = 0; i < arraycount; i++) 69 | // scanf("%d", a + i); 70 | // 71 | // result = MaxSubseqSum1(a, arraycount); 72 | // printf("%d",result); 73 | // 74 | // return 0; 75 | // } 76 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/01_2_Maximum_Subsequence_Sum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Maxsubsequencesum.cpp 3 | * 4 | * Created on: 2018年3月8日 5 | * Author: Administrator 6 | */ 7 | 8 | /* 9 | 01-复杂度2 Maximum Subsequence Sum(25 分) 10 | 11 | Given a sequence of K integers { N1, N2, ..., NK }. 12 | A continuous subsequence is defined to be { Ni, Ni+1, ..., Nj } where 1 <= i <= j <= K. 13 | The Maximum Subsequence is the continuous subsequence which has the largest sum of its elements. 14 | For example, given sequence { -2, 11, -4, 13, -5, -2 }, its maximum subsequence is { 11, -4, 13 } with the largest sum being 20. 15 | Now you are supposed to find the largest sum, together with the first and the last numbers of the maximum subsequence. 16 | Input Specification: 17 | Each input file contains one test case. Each case occupies two lines. 18 | The first line contains a positive integer K (<= 10000). The second line contains K numbers, separated by a space. 19 | Output Specification: 20 | For each test case, output in one line the largest sum, 21 | together with the first and the last numbers of the maximum subsequence. 22 | The numbers must be separated by one space, but there must be no extra space at the end of a line. 23 | In case that the maximum subsequence is not unique, output the one with the smallest indices i and j (as shown by the sample case). 24 | If all the K numbers are negative, then its maximum sum is defined to be 0, 25 | and you are supposed to output the first and the last numbers of the whole sequence. 26 | 27 | Sample Input: 28 | 10 -10 1 2 3 4 -5 -23 3 7 -21 29 | Sample Output: 30 | 10 1 4 31 | */ 32 | 33 | #include 34 | #include 35 | 36 | static int MaxSubseqSum2(int A[], int N) 37 | { 38 | int ThisSum, MaxSum; 39 | int i, array_end; 40 | ThisSum = MaxSum = 0; 41 | array_end = 0; 42 | int array_begin = 0; 43 | int allnative = 1; 44 | int zero_count = 1; 45 | int save_array_begin = 0; 46 | 47 | for (i = 0; i < N; i++) 48 | { 49 | ThisSum += A[i]; /* 向右累加 */ 50 | 51 | if (A[i] >= 0) 52 | allnative = 0; 53 | 54 | if (ThisSum > MaxSum) 55 | { 56 | MaxSum = ThisSum; /* 发现更大和则更新当前结果 */ 57 | zero_count++; 58 | array_end = i; 59 | save_array_begin = array_begin; 60 | } 61 | else if (ThisSum < 0) /* 如果当前子列和为负 */ 62 | { 63 | ThisSum = 0; /* 则不可能使后面的部分和增大,抛弃之 */ 64 | array_begin = i + 1; 65 | } 66 | } 67 | 68 | if (allnative) 69 | { 70 | printf("0 %d %d", A[0], A[N - 1]); 71 | return 0; 72 | } 73 | 74 | if (MaxSum == 0) 75 | { 76 | printf("0 0 0"); 77 | } 78 | else 79 | { 80 | printf("%d %d %d", MaxSum, A[save_array_begin], A[array_end]); 81 | } 82 | 83 | return 0; 84 | } 85 | 86 | // int main() 87 | //{ 88 | // int i, *a; 89 | // int arraycount; 90 | // scanf("%d",&arraycount); 91 | // 92 | // a = (int *)malloc(sizeof(int) * arraycount); /*分配内存*/ 93 | // 94 | // for(i = 0; i < arraycount; i++) 95 | // scanf("%d", a + i); 96 | // 97 | // MaxSubseqSum2(a, arraycount); 98 | // free(a); 99 | // return 0; 100 | // } 101 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/01_3_BinarySearch.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * BinarySearch.cpp 3 | * 4 | * Created on: 2018年4月7日 5 | * Author: Summer 6 | */ 7 | 8 | 9 | /* 10 | * 01-复杂度3 二分查找(20 分) 11 | 本题要求实现二分查找算法。 12 | 13 | 函数接口定义: 14 | 15 | Position BinarySearch( List L, ElementType X ); 16 | 其中List结构定义如下: 17 | 18 | typedef int Position; 19 | typedef struct LNode *List; 20 | struct LNode { 21 | ElementType Data[MAXSIZE]; 22 | Position Last; 23 | }; 24 | 25 | L是用户传入的一个线性表,其中ElementType元素可以通过>、==、<进行比较, 26 | 并且题目保证传入的数据是递增有序的。函数BinarySearch要查找X在Data中的位置, 27 | 即数组下标(注意:元素从下标1开始存储)。 28 | 找到则返回下标,否则返回一个特殊的失败标记NotFound。 29 | 30 | 裁判测试程序样例: 31 | 32 | #include 33 | #include 34 | 35 | #define MAXSIZE 10 36 | #define NotFound 0 37 | typedef int ElementType; 38 | 39 | typedef int Position; 40 | typedef struct LNode *List; 41 | struct LNode { 42 | ElementType Data[MAXSIZE]; 43 | Position Last; 44 | }; 45 | 46 | List ReadInput(); // 47 | Position BinarySearch( List L, ElementType X ); 48 | 49 | int main() 50 | { 51 | List L; 52 | ElementType X; 53 | Position P; 54 | 55 | L = ReadInput(); 56 | scanf("%d", &X); 57 | P = BinarySearch( L, X ); 58 | printf("%d\n", P); 59 | 60 | return 0; 61 | } 62 | 63 | // 你的代码将被嵌在这里 64 | 65 | 输入样例1: 66 | 67 | 5 68 | 12 31 55 89 101 69 | 31 70 | 输出样例1: 71 | 72 | 2 73 | 输入样例2: 74 | 75 | 3 76 | 26 78 233 77 | 31 78 | 输出样例2: 79 | 80 | 0 81 | 82 | */ 83 | 84 | #define MAXSIZE 10 85 | #define NotFound 0 86 | typedef int ElementType; 87 | 88 | typedef int Position; 89 | typedef struct LNode *List; 90 | struct LNode { 91 | ElementType Data[MAXSIZE]; 92 | Position Last; 93 | }; 94 | 95 | Position BinarySearch( List L, ElementType X ) 96 | { 97 | int low, mid, high; 98 | low = 1; 99 | high = L->Last; 100 | while( low <= high ) 101 | { 102 | mid = (low + high)/2; 103 | if ( L->Data[mid] < X ) 104 | low = mid + 1; 105 | else if( L->Data[mid] > X ) 106 | { 107 | high = mid - 1; 108 | }else{ 109 | return mid; 110 | } 111 | } 112 | return NotFound; 113 | } 114 | 115 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/02_1_List_Merge.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * List_Merge.cpp 3 | * 4 | * Created on: 2018年4月7日 5 | * Author: Summer 6 | */ 7 | 8 | /* 9 | * 10 | 02-线性结构1 两个有序链表序列的合并(15 分) 11 | 本题要求实现一个函数,将两个链表表示的递增整数序列合并为一个非递减的整数序列。 12 | 13 | 函数接口定义: 14 | 15 | List Merge( List L1, List L2 ); 16 | 其中List结构定义如下: 17 | 18 | typedef struct Node *PtrToNode; 19 | struct Node { 20 | ElementType Data; // 存储结点数据 21 | PtrToNode Next; // 指向下一个结点的指针 22 | }; 23 | typedef PtrToNode List; // 定义单链表类型 24 | L1和L2是给定的带头结点的单链表,其结点存储的数据是递增有序的;函数Merge要将L1和L2合并为一个非递减的整数序列。应直接使用原序列中的结点,返回归并后的带头结点的链表头指针。 25 | 26 | 裁判测试程序样例: 27 | 28 | #include 29 | #include 30 | 31 | typedef int ElementType; 32 | typedef struct Node *PtrToNode; 33 | struct Node { 34 | ElementType Data; 35 | PtrToNode Next; 36 | }; 37 | typedef PtrToNode List; 38 | 39 | List Read(); // 细节在此不表 40 | void Print( List L ); // 细节在此不表;空链表将输出NULL 41 | 42 | List Merge( List L1, List L2 ); 43 | 44 | int main() 45 | { 46 | List L1, L2, L; 47 | L1 = Read(); 48 | L2 = Read(); 49 | L = Merge(L1, L2); 50 | Print(L); 51 | Print(L1); 52 | Print(L2); 53 | return 0; 54 | } 55 | 56 | // 你的代码将被嵌在这里 57 | 58 | 输入样例: 59 | 60 | 3 61 | 1 3 5 62 | 5 63 | 2 4 6 8 10 64 | 输出样例: 65 | 66 | 1 2 3 4 5 6 8 10 67 | NULL 68 | NULL 69 | 70 | */ 71 | #include 72 | #include 73 | typedef int ElementType; 74 | typedef struct Node *PtrToNode; 75 | struct Node { 76 | ElementType Data; 77 | PtrToNode Next; 78 | }; 79 | typedef PtrToNode List; 80 | 81 | 82 | List Merge( List L1, List L2 ) 83 | { 84 | List p1 = L1->Next; 85 | List p2 = L2->Next; 86 | List L = (List)malloc(sizeof(struct Node)); 87 | List p = L; 88 | 89 | while(p1 != NULL && p2 != NULL) 90 | { 91 | if(p1->Data < p2->Data) 92 | { 93 | p->Next = p1; 94 | p1 = p1->Next; 95 | L1->Next = p1; 96 | p = p->Next; 97 | } else 98 | { 99 | p->Next = p2; 100 | p2 = p2->Next; 101 | L2->Next = p2; 102 | p = p->Next; 103 | } 104 | } 105 | 106 | if(p1 != NULL) 107 | { 108 | p->Next = p1; 109 | L1->Next = NULL; 110 | } 111 | 112 | if(p2 != NULL) 113 | { 114 | p->Next = p2; 115 | L2->Next = NULL; 116 | } 117 | 118 | return L; 119 | 120 | } 121 | 122 | //有序链表的合并 123 | List List_Merge(List L1, List L2) { 124 | if (L1 == NULL) { 125 | return L2; 126 | } else if (L2 == NULL) { 127 | return L1; 128 | } else if (L1->Data <= L2->Data) { 129 | List list_1 = L1->Next; 130 | List list = List_Merge(list_1, L2); 131 | L1->Next = list; 132 | return L1; 133 | } else { 134 | List list_2 = L2->Next; 135 | List list = List_Merge(list_2, L1); 136 | L2->Next = list; 137 | return L2; 138 | } 139 | } 140 | 141 | List Recurse_Merge(List L1, List L2) { 142 | List L = (List) malloc(sizeof(struct Node)); 143 | List L1_ = L1->Next; 144 | List L2_ = L2->Next; 145 | L1->Next = NULL; 146 | L2->Next = NULL; 147 | 148 | L->Next = List_Merge(L1_, L2_); 149 | return L; 150 | } 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/02_2_list_mult_add.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * list_mult_add.cpp 3 | * 4 | * Created on: 2018年4月1日 5 | * Author: Summer 6 | */ 7 | 8 | /* 9 | 02-线性结构2 一元多项式的乘法与加法运算 10 | 11 | 设计函数分别求两个一元多项式的乘积与和。 12 | 13 | 输入格式: 14 | 15 | 输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。 16 | 数字间以空格分隔。 17 | 18 | 输出格式: 19 | 20 | 输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。 21 | 零多项式应输出0 0。 22 | 23 | 输入样例: 24 | 25 | 4 3 4 -5 2 6 1 -2 0 26 | 3 5 20 -7 4 3 1 27 | 输出样例: 28 | 29 | 15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1 30 | 5 20 -4 4 -5 2 9 1 -2 0 31 | */ 32 | 33 | #include 34 | #include 35 | 36 | struct PolyNode { 37 | int coef; // 系数 38 | int expon; // 指数 39 | struct PolyNode *link; // 指向下一个节点的指针 40 | }; 41 | typedef struct PolyNode *Polynomial; 42 | Polynomial P1, P2; 43 | 44 | // 系数 指数 需要将节点插入链表的尾部指针 45 | void Attach(int c, int e, Polynomial *pRear) { 46 | Polynomial P; 47 | 48 | P = (Polynomial) malloc(sizeof(struct PolyNode)); 49 | P->coef = c; 50 | P->expon = e; 51 | P->link = NULL; 52 | (*pRear)->link = P; //让尾节点的指针指向新的节点 53 | *pRear = P; //更新尾指针指向的位置 54 | } 55 | 56 | Polynomial ReadPoly() { 57 | int c, e, N; 58 | Polynomial P,Rear,t; 59 | 60 | scanf("%d", &N); 61 | P = (Polynomial)malloc(sizeof(struct PolyNode)); 62 | P->link = NULL; 63 | Rear = P; 64 | 65 | while (N--) { 66 | scanf("%d %d", &c, &e); 67 | Attach(c, e, &Rear); 68 | } 69 | 70 | t = P; 71 | P = P->link; 72 | free(t); 73 | 74 | return P; 75 | } 76 | 77 | Polynomial Add(Polynomial P1, Polynomial P2) { 78 | Polynomial Rear, t1, t2, P; 79 | t1 = P1; 80 | t2 = P2; 81 | P = (Polynomial) malloc(sizeof(struct PolyNode)); 82 | P->link = NULL; 83 | Rear = P; 84 | 85 | while (t1 && t2) { 86 | //如果指数相同,那么将系数相加,然后插入到P上 87 | if (t1->expon == t2->expon) { 88 | //如果系数和不为0 89 | if(t1->coef + t2->coef) 90 | { 91 | Attach((t1->coef + t2->coef), t1->expon, &Rear); 92 | t1 = t1->link; 93 | t2 = t2->link; 94 | }else{ 95 | //系数和为0 96 | t1 = t1->link; 97 | t2 = t2->link; 98 | } 99 | } else if (t1->expon > t2->expon) { 100 | //如果t1的指数大于t2的指数,那么将t1插入P,并t1指向下一个元素 101 | Attach(t1->coef, t1->expon, &Rear); 102 | t1 = t1->link; 103 | 104 | } else { 105 | //t2的指数大于t1,那么将t2插入P,并t2指向下一个元素 106 | Attach(t2->coef, t2->expon, &Rear); 107 | t2 = t2->link; 108 | } 109 | } 110 | 111 | //t1不为空,将t1后面的元素依次插入到P中 112 | while (t1) { 113 | Attach(t1->coef, t1->expon, &Rear); 114 | t1 = t1->link; 115 | } 116 | 117 | //t2不为空,将t2后面的元素依次插入到P中 118 | while (t2) { 119 | Attach(t2->coef, t2->expon, &Rear); 120 | t2 = t2->link; 121 | } 122 | 123 | //函数返回 124 | t2 = P; 125 | P = P->link; 126 | free(t2); 127 | 128 | return P; 129 | } 130 | 131 | Polynomial Mult(Polynomial P1, Polynomial P2) 132 | { 133 | Polynomial Rear, t1, t2, P, t; 134 | t1 = P1; 135 | t2 = P2; 136 | int c, e; 137 | 138 | if(!P1 || !P2) return NULL; 139 | 140 | P = (Polynomial) malloc(sizeof(struct PolyNode)); 141 | P->link = NULL; 142 | Rear = P; 143 | 144 | while(t2) //用t1的第一项乘以P2,得到第一个链P 145 | { 146 | Attach(t1->coef * t2->coef,t1->expon + t2->expon, &Rear); 147 | t2 = t2->link; 148 | } 149 | 150 | t1 = t1->link; 151 | 152 | while(t1) //再用两个循环将后续的项加入到链表中 153 | { 154 | t2 = P2; 155 | Rear = P; 156 | while(t2){ 157 | e = t1->expon + t2->expon; 158 | c = t1->coef * t2->coef; 159 | 160 | //查找到系数不比e大的位置后停下来 161 | while(Rear->link && (Rear->link->expon > e)) 162 | Rear = Rear->link; 163 | 164 | //如果Rear当前节点的下一个参数的指数项和需要插入的项相同,那么需要合并 165 | if(Rear->link && (Rear->link->expon == e)) 166 | { 167 | if((Rear->link->coef + c) != 0) //如果和不为0,那么更新系数 168 | Rear->link->coef += c; 169 | else{ 170 | t = Rear->link; 171 | Rear->link = t->link; 172 | free(t); 173 | } 174 | }else{ 175 | //不相同则生成一个新节点直接插入 176 | t = (Polynomial) malloc(sizeof(struct PolyNode)); 177 | t->coef = c; 178 | t->expon = e; 179 | 180 | t->link = Rear->link; //插入新的节点 181 | Rear->link = t; 182 | Rear = Rear->link; 183 | } 184 | t2 = t2->link; 185 | } 186 | t1 = t1->link; 187 | } 188 | 189 | //函数返回 190 | t2 = P; 191 | P = P->link; 192 | free(t2); 193 | 194 | return P; 195 | } 196 | 197 | void PrintPoly(Polynomial P) { 198 | int flag = 0; 199 | 200 | if (!P) { 201 | printf("0 0\n"); 202 | return; 203 | } 204 | 205 | while (P) { 206 | if (!flag) { 207 | flag = 1; 208 | } else { 209 | printf(" "); 210 | } 211 | 212 | printf("%d %d", P->coef, P->expon); 213 | P = P->link; 214 | } 215 | 216 | printf("\n"); 217 | } 218 | 219 | //int main() { 220 | // Polynomial P1, P2, PP, PS; 221 | // P1 = ReadPoly(); 222 | // P2 = ReadPoly(); 223 | // PP = Mult(P1, P2); 224 | // PrintPoly(PP); 225 | // PS = Add(P1, P2); 226 | // PrintPoly(PS); 227 | // return 0; 228 | //} 229 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/02_3_Reversing_Linked_List.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Reversing_Linked_List.cpp 3 | * 4 | * Created on: 2018年4月6日 5 | * Author: Administrator 6 | */ 7 | 8 | /* 9 | 02-线性结构3 Reversing Linked List(25 分) 10 | 11 | Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. 12 | For example, given L being 1→2→3→4→5→6, if K = 3, then you must output 3→2→1→6→5→4; if K = 4, 13 | you must output 4→3→2→1→5→6. 14 | 15 | Input Specification: 16 | 17 | Each input file contains one test case. For each case, the first line contains the address of the first node, 18 | a positive N (<= 105) which is the total number of nodes, 19 | and a positive K (<=N) which is the length of the sublist to be reversed. 20 | The address of a node is a 5-digit nonnegative integer, and NULL is represented by -1. 21 | 22 | Then N lines follow, each describes a node in the format: 23 | 24 | Address Data Next 25 | 26 | where Address is the position of the node, Data is an integer, and Next is the position of the next node. 27 | 28 | Output Specification: 29 | 30 | For each case, output the resulting ordered linked list. Each node occupies a line, 31 | and is printed in the same format as in the input. 32 | 33 | Sample Input: 34 | 00100 6 4 35 | 00000 4 99999 36 | 00100 1 12309 37 | 68237 6 -1 38 | 33218 3 00000 39 | 99999 5 68237 40 | 12309 2 33218 41 | Sample Output: 42 | 00000 4 33218 43 | 33218 3 12309 44 | 12309 2 00100 45 | 00100 1 99999 46 | 99999 5 68237 47 | 68237 6 -1 48 | */ 49 | 50 | 51 | #include 52 | #include 53 | 54 | struct DataNode { 55 | int addr; 56 | int data; 57 | int nextaddr; 58 | struct DataNode *link; 59 | }; 60 | typedef struct DataNode *DataList; 61 | 62 | // 系数 指数 需要将节点插入链表的尾部指针 63 | static void Attach(int addr, int data, int nextaddr, DataList *pRear) { 64 | DataList P; 65 | 66 | P = (DataList) malloc(sizeof(struct DataNode)); 67 | P->addr = addr; 68 | P->data = data; 69 | P->nextaddr = nextaddr; 70 | P->link = NULL; 71 | (*pRear)->link = P; //让尾节点的指针指向新的节点 72 | *pRear = P; //更新尾指针指向的位置 73 | } 74 | 75 | int first_addr, data_num, k; 76 | 77 | //1、将数据读入一个链表内 78 | DataList DataNode_read() { 79 | 80 | int addr, data, nextaddr , datanumber; 81 | DataList P, Rear, t; 82 | 83 | scanf("%d %d %d", &first_addr, &data_num, &k); 84 | datanumber = data_num; 85 | 86 | P = (DataList) malloc(sizeof(struct DataNode)); 87 | P->link = NULL; 88 | Rear = P; 89 | 90 | while (datanumber--) { 91 | scanf("%d %d %d", &addr, &data, &nextaddr); 92 | Attach(addr, data, nextaddr, &Rear); 93 | } 94 | 95 | t = P; 96 | P = P->link; 97 | free(t); 98 | 99 | return P; 100 | } 101 | 102 | //2、对链表进行重新排序,查找之前生成的链表中第一个地址的节点插入 103 | //然后根据下一个地址查找后插入 104 | 105 | DataList DataNode_rearrangement(DataList List, int firstaddr, int data_num) { 106 | DataList P, Rear, t; 107 | P = (DataList) malloc(sizeof(struct DataNode)); 108 | P->link = NULL; 109 | Rear = P; 110 | DataList List_t = List; 111 | 112 | while (data_num--) { 113 | while (List_t) { 114 | if (List_t->addr == firstaddr) { 115 | Attach(List_t->addr, List_t->data, List_t->nextaddr, &Rear); 116 | firstaddr = List_t->nextaddr; 117 | break; 118 | } else { 119 | List_t = List_t->link; 120 | } 121 | } 122 | List_t = List; 123 | } 124 | 125 | t = P; 126 | P = P->link; 127 | free(t); 128 | 129 | return P; 130 | } 131 | 132 | //链表的反转 133 | DataList ListReversing(DataList List) { 134 | DataList p = List, newH = NULL; 135 | while (p != NULL) //一直迭代到链尾 136 | { 137 | if (p->link != NULL) { 138 | p->link->nextaddr = p->addr; 139 | } 140 | 141 | DataList tmp = p->link; //暂存p下一个地址,防止变化指针指向后找不到后续的数 142 | p->link = newH; //p->next指向前一个空间 143 | newH = p; //新链表的头移动到p,扩长一步链表 144 | p = tmp; //p指向原始链表p指向的下一个空间 145 | } 146 | 147 | return newH; 148 | } 149 | 150 | void DataListprint(DataList List); 151 | 152 | DataList DataListReversing(DataList List, int data_num, int k) { 153 | int z,remainder; 154 | int i = 1; 155 | int flag = 1; 156 | z = data_num / k; 157 | remainder = data_num % k; 158 | 159 | if(k == 1) 160 | return List; 161 | 162 | DataList P, Rear, t; 163 | P = (DataList) malloc(sizeof(struct DataNode)); 164 | P->link = NULL; 165 | Rear = P; 166 | 167 | DataList List_t = List; 168 | int times_inter, times_out; 169 | DataList list_last_time = NULL, save_addr = NULL, next_addr = NULL; 170 | 171 | //如果刚好余数为0,那么要每次截取 K 个来反转,截取 z 次 172 | while (i <= z) { 173 | times_inter = k; 174 | 175 | while (--times_inter) { 176 | List_t = List_t->link; 177 | } 178 | 179 | if (List_t->link != NULL) { 180 | next_addr = List_t->link; //将下一个链表的第一个元素的地址存起来 这里可能等于 NULL 181 | } 182 | 183 | List_t->link = NULL; 184 | 185 | if (i == 1) { 186 | List_t = List; 187 | } else { 188 | List_t = next_addr; 189 | } 190 | 191 | //因为要反转链表 所以这时候放进去的 List_t 会是反转后的最后一个元素的指针 192 | save_addr = List_t; //这一轮没有反转前的最后一个元素的地址,用到最后表示链表的最后一个元素 193 | list_last_time = ListReversing(List_t); 194 | 195 | Rear->link = list_last_time; //将新的反转好的链表加入到新链表中 196 | Rear->nextaddr = list_last_time->addr; 197 | 198 | Rear = save_addr; //Rear指针指向新链表最后一个元素 199 | 200 | List_t = next_addr; // 201 | 202 | i++; 203 | } 204 | 205 | if (!remainder) { 206 | Rear->nextaddr = -1; //这里需要反转后的最后一个元素 207 | } else { 208 | Rear->link = next_addr; 209 | Rear->nextaddr = next_addr->addr; 210 | } 211 | 212 | t = P; 213 | P = P->link; 214 | free(t); 215 | 216 | return P; 217 | } 218 | 219 | void DataListprint(DataList List) { 220 | while (List) { 221 | if (List->nextaddr != -1) { 222 | printf("%05d %d %05d\n", List->addr, List->data, List->nextaddr, List); 223 | } else { 224 | printf("%05d %d %d\n", List->addr, List->data, List->nextaddr, List); 225 | } 226 | List = List->link; 227 | } 228 | } 229 | 230 | //int main() { 231 | // DataList save, p, p_rearrangement, p_output; 232 | // int count = 0; 233 | // //1、读入链表 234 | // p = DataNode_read(); 235 | //// printf("读入的链表如下: \n"); 236 | //// DataListprint(p); 237 | // //2、重新排序 238 | // p_rearrangement = DataNode_rearrangement(p, first_addr, data_num); 239 | // save = p_rearrangement; 240 | //// printf("重新排序后的链表如下: \n"); 241 | //// DataListprint(p_rearrangement); 242 | // 243 | // while (p_rearrangement) { 244 | // count++; 245 | // p_rearrangement = p_rearrangement->link; 246 | // } 247 | // 248 | // //printf("反转后的链表如下: p_output = %p \n", p_output); 249 | // //3、反转链表 250 | // p_output = DataListReversing(save, count, k); 251 | // //4、输出链表 252 | //// printf("反转后的链表如下: p_output = %p \n", p_output); 253 | // DataListprint(p_output); 254 | // 255 | // return 0; 256 | //} 257 | 258 | 259 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/02_4_Pop_Sequence.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Pop_Sequence.cpp 3 | * 4 | * Created on: 2018年4月6日 5 | * Author: Administrator 6 | */ 7 | 8 | /* 9 | 02-线性结构4 Pop Sequence(25 分) 10 | 11 | Given a stack which can keep M numbers at most. Push N numbers in the order of 1, 2, 3, ..., N and pop randomly. 12 | You are supposed to tell if a given sequence of numbers is a possible pop sequence of the stack. 13 | For example, if M is 5 and N is 7, we can obtain 1, 2, 3, 4, 5, 6, 7 from the stack, but not 3, 2, 1, 7, 5, 6, 4. 14 | 15 | Input Specification: 16 | 17 | Each input file contains one test case. 18 | For each case, the first line contains 3 numbers (all no more than 1000): 19 | M (the maximum capacity of the stack), N (the length of push sequence), and K (the number of pop sequences to be checked). 20 | Then K lines follow, each contains a pop sequence of N numbers. All the numbers in a line are separated by a space. 21 | 22 | Output Specification: 23 | 24 | For each pop sequence, print in one line "YES" if it is indeed a possible pop sequence of the stack, or "NO" if not. 25 | 26 | Sample Input: 27 | 28 | 5 7 5 29 | 30 | 1 2 3 4 5 6 7 31 | 32 | 3 2 1 7 5 6 4 33 | 34 | 7 6 5 4 3 2 1 35 | 36 | 5 6 4 3 7 2 1 37 | 38 | 1 7 6 5 4 3 2 39 | 40 | Sample Output: 41 | 42 | YES 43 | 44 | NO 45 | 46 | NO 47 | 48 | YES 49 | 50 | NO 51 | 52 | */ 53 | 54 | 55 | #include 56 | #include 57 | using namespace std; 58 | 59 | //假设 1-(i-1) 都进入了栈,i 还没有进入栈。 60 | //一个一个元素考虑出栈序列的元素x: 61 | //1. i>x 62 | // 这时X已经入过栈了。 63 | //1.1 如果他不是栈顶那么就无法pop出x了 64 | //1.2 如果x是栈顶,直接从堆栈pop就可以了,处理下一个出栈元素 65 | // 66 | //2. i<=x 67 | //2.1 这时候X还没有入栈,要想要让X出栈,我们必须把从i到x都push到栈,这时候x在栈顶,Pop即可。 68 | //注意:压入元素要保证栈里面的元素个数不超过给定的栈容量,否则也不可能将x弹出。 69 | 70 | int pop_seqence_test() { 71 | stack st; 72 | int stack_cap, test_seq_len, k; 73 | scanf("%d%d%d", &stack_cap, &test_seq_len, &k); //依次输入栈的容量,输入测试序列的长度,测试序列的组数, 74 | while (k--) { //对每一组测试序列分别进行测试 75 | int t = test_seq_len; 76 | int num = 1; //每次push到栈中的数字大小的记录 77 | bool flag = true; 78 | while (t--) { //对测试序列的每一个输入数据进行测试 79 | int x; 80 | scanf("%d", &x); //读入一个测试数据x 81 | while (num <= x) //x比当前栈顶下标要大 82 | st.push(num++); //一直push元素直到入栈的数字大小和x相等 83 | int last = st.top(); //查看栈顶元素 84 | if (last != x || st.size() > stack_cap) //如果栈顶元素不等于x,或者栈的大小已经超过栈容量则失败 85 | flag = false; 86 | st.pop(); //栈顶元素和x相等,且不超容量则弹栈 87 | } 88 | if (flag) 89 | printf("YES\n"); 90 | else 91 | printf("NO\n"); 92 | } 93 | return 0; 94 | } 95 | 96 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/03_1_Tree_isomorphism.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Tree_isomorphism.cpp 3 | * 4 | * Created on: 2018年4月14日 5 | * Author: SummerGift 6 | */ 7 | 8 | /* 9 | 03-树1 树的同构(25 分) 10 | 11 | 给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。 12 | 例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A、B、G的左右孩子互换后,就得到另外一棵树。而图2就不是同构的。 13 | 14 | 现给定两棵树,请你判断它们是否是同构的。 15 | 输入格式: 16 | 17 | 输入给出2棵二叉树树的信息。对于每棵树,首先在一行中给出一个非负整数N (≤10),即该树的结点数(此时假设结点从0到N−1编号); 18 | 随后N行,第i行对应编号第i个结点,给出该结点中存储的1个英文大写字母、其左孩子结点的编号、右孩子结点的编号。 19 | 如果孩子结点为空,则在相应位置上给出“-”。给出的数据间用一个空格分隔。注意:题目保证每个结点中存储的字母是不同的。 20 | 21 | 输出格式: 22 | 23 | 如果两棵树是同构的,输出“Yes”,否则输出“No”。 24 | 25 | 输入样例1(对应图1): 26 | 27 | 8 28 | A 1 2 29 | B 3 4 30 | C 5 - 31 | D - - 32 | E 6 - 33 | G 7 - 34 | F - - 35 | H - - 36 | 8 37 | G - 4 38 | B 7 6 39 | F - - 40 | A 5 1 41 | H - - 42 | C 0 - 43 | D - - 44 | E 2 - 45 | 输出样例1: 46 | 47 | Yes 48 | 输入样例2(对应图2): 49 | 50 | 8 51 | B 5 7 52 | F - - 53 | A 0 3 54 | C 6 - 55 | H - - 56 | D - - 57 | G 4 - 58 | E 1 - 59 | 8 60 | D 6 - 61 | B 5 - 62 | E - - 63 | H - - 64 | C 0 2 65 | G - 3 66 | F - - 67 | A 1 4 68 | 输出样例2: 69 | 70 | No 71 | */ 72 | 73 | #include 74 | #include 75 | 76 | #define MaxTree 10 77 | #define ElementType char 78 | #define Tree int 79 | #define Null -1 80 | 81 | struct TreeNode 82 | { 83 | ElementType data; 84 | Tree Left; 85 | Tree Right; 86 | } T1[MaxTree], T2[MaxTree]; 87 | 88 | static Tree buildtree(struct TreeNode T[]) { 89 | int N, check[MaxTree], root = Null; 90 | char cl, cr; 91 | 92 | scanf("%d\n", &N); 93 | 94 | if (N) { 95 | for (int i = 0; i < N; i++) 96 | check[i] = 0; 97 | 98 | for (int i = 0; i < N; i++) { 99 | scanf("%c %c %c\n", &T[i].data, &cl, &cr); //将数据输入,建立树,查找 ROOT 100 | 101 | if (cl != '-') { 102 | T[i].Left = cl - '0'; 103 | check[T[i].Left] = 1; 104 | } else { 105 | T[i].Left = Null; 106 | } 107 | if (cr != '-') { 108 | T[i].Right = cr - '0'; 109 | check[T[i].Right] = 1; 110 | } else { 111 | T[i].Right = Null; 112 | } 113 | } 114 | 115 | for (int i = 0; i < N; i++) 116 | if (!check[i]) { 117 | root = i; //T[i]中沒有任何节点的left和 right指向他,就是根节点 118 | break; 119 | } 120 | } 121 | return root; 122 | } 123 | 124 | static int Isomorphic( Tree R1, Tree R2) { 125 | if ((R1 == Null) && (R2 == Null)) //都是空树,同构 126 | return 1; 127 | if (((R1 == Null) && (R2 != Null)) || ((R1 != Null) && (R2 == Null))) 128 | return 0; //有一个是空树,不是同构 129 | if (T1[R1].data != T2[R2].data) 130 | return 0; //树根不一样,不是同构 131 | if ((T1[R1].Left == Null) && (T2[R2].Left == Null)) //都没有左树,判断右树是否相同 132 | return Isomorphic(T1[R1].Right, T2[R2].Right); 133 | 134 | if ((T1[R1].Left != Null) && (T2[R2].Left != Null) 135 | && (T1[T1[R1].Left].data == T2[T2[R2].Left].data)) //两树左子树皆不空,且值相等 136 | return (Isomorphic(T1[R1].Left, T2[R2].Left) 137 | && Isomorphic(T1[R1].Right, T2[R2].Right)); //判断其子树 138 | else { 139 | return (Isomorphic(T1[R1].Left, T2[R2].Right) && //交换左右子树判断 140 | Isomorphic(T1[R1].Right, T2[R2].Left)); 141 | } 142 | } 143 | 144 | //int main() 145 | //{ 146 | // Tree r1, r2; 147 | // r1 = buildtree(T1); 148 | // r2 = buildtree(T2); 149 | // 150 | // if (Isomorphic(r1, r2)) { 151 | // printf("Yes\n"); 152 | // } else { 153 | // printf("No\n"); 154 | // } 155 | // 156 | // return 0; 157 | //} 158 | 159 | 160 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/03_2_List_Leaves.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 03_2_List_Leaves.cpp 3 | * 4 | * Created on: 2018年4月19日 5 | * Author: SummerGift 6 | */ 7 | 8 | /* 9 | 03-树2 List Leaves(25 分) 10 | Given a tree, you are supposed to list all the leaves in the order of top down, and left to right. 11 | 12 | Input Specification: 13 | 14 | Each input file contains one test case. For each case, 15 | the first line gives a positive integer N (≤10) which is the total number of nodes in the tree -- and hence the nodes are numbered from 0 to N−1. 16 | Then N lines follow, each corresponds to a node, 17 | and gives the indices of the left and right children of the node. 18 | If the child does not exist, a "-" will be put at the position. 19 | Any pair of children are separated by a space. 20 | 21 | Output Specification: 22 | 23 | For each test case, print in one line all the leaves' indices in the order of top down, 24 | and left to right. There must be exactly one space between any adjacent numbers, 25 | and no extra space at the end of the line. 26 | 27 | 28 | Sample Input: 29 | 30 | 8 31 | 1 - 32 | - - 33 | 0 - 34 | 2 7 35 | - - 36 | - - 37 | 5 - 38 | 4 6 39 | Sample Output: 40 | 41 | 4 1 5 42 | */ 43 | 44 | 45 | //通过顺序输入,结构体数组存储的树,第一步是要找到这棵树的根节点 46 | //根节点有一个特殊的性质就是没有人指向它,所以需要一个标记数组来记录节点是否有其他节点指向它 47 | 48 | #include 49 | #include 50 | #include 51 | 52 | using namespace std; 53 | 54 | typedef int tree; 55 | #define Null -1 56 | 57 | struct treenode { 58 | int data; 59 | tree left; 60 | tree right; 61 | }; 62 | 63 | //接收数据,将数据存储起来,建树,返回树的根节点 64 | tree buildtree(vector &tree_in, int n) { 65 | tree root = -1; 66 | char cl, cr; 67 | vector check(n, 0); //定义check包含 n 个 int 类型的元素,每个元素都被初始化为0 68 | 69 | for (int i = 0; i < n; i++) { 70 | cin >> cl >> cr; 71 | tree_in[i].data = i; 72 | if (cl != '-') { 73 | tree_in[i].left = (int) (cl - '0'); 74 | check[tree_in[i].left] = 1; 75 | } else { 76 | tree_in[i].left = Null; 77 | } 78 | 79 | if (cr != '-') { 80 | tree_in[i].right = (int) (cr - '0'); 81 | check[tree_in[i].right] = 1; 82 | } else { 83 | tree_in[i].right = Null; 84 | } 85 | } 86 | 87 | for (int i = 0; i < n; i++) 88 | if (!check[i]) { 89 | root = i; 90 | break; 91 | } 92 | 93 | return root; 94 | } 95 | 96 | /* 97 | queue 的基本操作有: 98 | 入队,如例:q.push(x); 将x 接到队列的末端。 99 | 出队,如例:q.pop(); 弹出队列的第一个元素,注意,并不会返回被弹出元素的值。 100 | 访问队首元素,如例:q.front(),即最早被压入队列的元素。 101 | 访问队尾元素,如例:q.back(),即最后被压入队列的元素。 102 | 判断队列空,如例:q.empty(),当队列空时,返回true。 103 | 访问队列中的元素个数,如例:q.size() 104 | 105 | push_back 容器类型在尾部加入数据。 106 | */ 107 | 108 | vector findleaves(const vector &tree_in, tree root) { 109 | vector leaves; 110 | queue save_quque; 111 | treenode node; 112 | 113 | if (root == Null) 114 | return {}; 115 | save_quque.push(tree_in[root]); 116 | while (!save_quque.empty()) { 117 | node = save_quque.front(); 118 | save_quque.pop(); 119 | 120 | //如果该节点的左右儿子都不存在则为叶节点 121 | if ((node.left == Null) && (node.right == Null)) 122 | leaves.push_back(node.data); 123 | if (node.left != Null) 124 | save_quque.push(tree_in[node.left]); 125 | if (node.right != Null) 126 | save_quque.push(tree_in[node.right]); 127 | } 128 | 129 | return leaves; 130 | } 131 | 132 | //decltype 查询表达式的数据类型 133 | 134 | /* 135 | int main() { 136 | int n; 137 | tree root; 138 | 139 | cin >> n; 140 | vector Tree(10); 141 | root = buildtree(Tree, n); 142 | 143 | auto result = findleaves(Tree, root); //接收返回的存储着叶子节点的队列,将队列遍历输出 144 | 145 | for (decltype(result.size()) i = 0; i != result.size(); i++) { 146 | cout << result[i]; 147 | //注意:最后一个数字输出后没有空格 148 | i != result.size() - 1 ? cout << " " : cout << endl; 149 | } 150 | 151 | return 0; 152 | } 153 | */ 154 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/03_3_Tree_Traversals_Again.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 03_3_Tree_Traversals_Again.cpp 3 | * 4 | * Created on: 2018年4月22日 5 | * Author: SummerGift 6 | */ 7 | 8 | /* 9 | 03-树3 Tree Traversals Again(25 分) 10 | An inorder binary tree traversal can be implemented in a non-recursive way with a stack. 11 | For example, suppose that when a 6-node binary tree (with the keys numbered from 1 to 6) is traversed, 12 | the stack operations are: push(1); push(2); push(3); pop(); pop(); push(4); pop(); pop(); push(5); push(6); pop(); pop(). 13 | Then a unique binary tree (shown in Figure 1) can be generated from this sequence of operations. 14 | Your task is to give the postorder traversal sequence of this tree. 15 | 16 | 一个中序遍历的二叉树可以使用一个栈结构来非递归遍历。比如说一个六个节点的二叉树被遍历,带着值 1 - 6。 17 | 栈的操作为 P1 P2 P3 POP POP P4 POP POP P5 P6 POP POP 18 | 接下来特殊的二叉树可以被这一系列的操作产生。 19 | 你的任务是给出这棵树的后序遍历序列。 20 | 21 | Figure 1 22 | Input Specification: 23 | 24 | Each input file contains one test case. For each case, 25 | the first line contains a positive integer N (≤30) which is the total number of nodes in a tree (and hence the nodes are numbered from 1 to N). 26 | Then 2N lines follow, each describes a stack operation in the format: "Push X" where X is the index of the node being pushed onto the stack; 27 | or "Pop" meaning to pop one node from the stack. 28 | 29 | 第一行包括一个小于等于30的正整数,代表树总共的结点数。接下来会有2N行,每一行描述栈操作 PUSH X 指的是将这个节点压入栈中,POP 操作的意思是将节点从栈中弹出。 30 | 31 | Output Specification: 32 | 33 | For each test case, print the postorder traversal sequence of the corresponding tree in one line. 34 | A solution is guaranteed to exist. All the numbers must be separated by exactly one space, 35 | and there must be no extra space at the end of the line. 36 | 37 | 用一行打出相关树的后序输出。 38 | 39 | Sample Input: 40 | 41 | 6 42 | Push 1 43 | Push 2 44 | Push 3 45 | Pop 46 | Pop 47 | Push 4 48 | Pop 49 | Pop 50 | Push 5 51 | Push 6 52 | Pop 53 | Pop 54 | 55 | Sample Output: 56 | 57 | 3 4 2 6 5 1 58 | */ 59 | 60 | /* 61 | * 递归遍历和非递归中序遍历树,递归遍历是先递归的访问树的左子树,然后打印出根节点,然后递归访问右子树。 62 | * 而非递归中序遍历的情况,是我们自己创建一个栈,先将根节点入栈,然后访问左子树,然后把子树的根节点压入栈。 63 | * 在非递归中序遍历 PUSH 的顺序是先序遍历的顺序,POP 的顺序相当于是中序遍历的结果。 64 | * 这个题目就变成了知道了一个树的先序和中序遍历结果,求后续遍历结果。 65 | */ 66 | 67 | #include 68 | #include 69 | #include 70 | #include 71 | 72 | using namespace std; 73 | 74 | 75 | //将输入的内容纪录下来,分别存入先序遍历数组和中序遍历数组 76 | vector> getorder(int n) { 77 | vector preorder(n, 0); 78 | vector inorder(n, 0); 79 | stack st; 80 | int prel = 0, inl = 0; 81 | 82 | for (int i = 0; i < 2 * n; i++) { 83 | string str; 84 | int tmp; 85 | cin >> str; 86 | if (str == "Push") { 87 | cin >> tmp; 88 | preorder[prel++] = tmp; 89 | st.push(tmp); 90 | } else if (str == "Pop") { 91 | inorder[inl++] = st.top(); 92 | st.pop(); 93 | } 94 | } 95 | 96 | return {preorder, inorder}; 97 | } 98 | 99 | //输入先序遍历数组和中序遍历数组,返回后序遍历数组 100 | 101 | void getpostorder(vector preorder, int prel, vector inorder, int inl, 102 | vector &postorder, int postl, int n) { 103 | if (n == 0) 104 | return; 105 | if (n == 1) { 106 | postorder[postl] = preorder[prel]; 107 | return; 108 | } 109 | 110 | auto root = preorder[prel]; //从先序遍历的第一个节点拿到根节点 111 | postorder[postl + n - 1] = root; //放在后序遍历的最后一个位置上 112 | 113 | //在中序遍历数组上找出 ROOT 的位置 114 | int i = 0; 115 | while (i < n) { 116 | if (inorder[inl + i] == root) 117 | break; 118 | i++; 119 | } 120 | 121 | //计算出 ROOT 节点左右子树节点的个数 122 | int L = i, R = n - i - 1; 123 | 124 | getpostorder(preorder, prel + 1, inorder, inl, postorder, postl, L); 125 | getpostorder(preorder, prel + L + 1, inorder, inl + L + 1, postorder, 126 | postl + L, R); 127 | } 128 | 129 | 130 | 131 | /* 132 | * 先将先序和中序遍历的输出存入数组,然后再从中得到后序遍历的输出。 133 | */ 134 | 135 | int main() { 136 | int n; 137 | cin >> n; 138 | auto res = getorder(n); 139 | vector postorder(n, 0); 140 | getpostorder(res[0], 0, res[1], 0, postorder, 0, n); 141 | 142 | int i = 0; 143 | for (; i < n - 1; i++) { 144 | cout << postorder[i] << " "; 145 | } 146 | cout << postorder[i] << endl; 147 | return 0; 148 | } 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/04_4_IsSameBinarySearchTree.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 04_4_IsSameBinarySearchTree.cpp 3 | * 4 | * Created on: 2018年4月27日 5 | * Author: SummerGift 6 | */ 7 | 8 | /* 9 | * 04-树4 是否同一棵二叉搜索树(25 分) 10 | 给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果。于是对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树。 11 | 12 | 输入格式: 13 | 输入包含若干组测试数据。每组数据的第1行给出两个正整数N (≤10)和L,分别是每个序列插入元素的个数和需要检查的序列个数。第2行给出N个以空格分隔的正整数,作为初始插入序列。最后L行,每行给出N个插入的元素,属于L个需要检查的序列。 14 | 15 | 简单起见,我们保证每个插入序列都是1到N的一个排列。当读到N为0时,标志输入结束,这组数据不要处理。 16 | 17 | 输出格式: 18 | 对每一组需要检查的序列,如果其生成的二叉搜索树跟对应的初始序列生成的一样,输出“Yes”,否则输出“No”。 19 | 20 | 输入样例: 21 | 4 2 22 | 3 1 4 2 23 | 3 4 1 2 24 | 3 2 4 1 25 | 2 1 26 | 2 1 27 | 1 2 28 | 0 29 | 输出样例: 30 | Yes 31 | No 32 | No 33 | */ 34 | 35 | //解本题用到的方法是先建立一棵树,然后依照这个树分别判别后面的L个序列能否与T形成同一个搜索树并输出结果 36 | #include 37 | #include 38 | 39 | typedef struct treenode *tree; 40 | struct treenode { 41 | int v; 42 | tree left, right; 43 | int flag; 44 | }; 45 | 46 | //创建一个新的结点 47 | tree new_node(int v) { 48 | tree t = (tree) malloc(sizeof(struct treenode)); 49 | t->v = v; 50 | t->left = t->right = NULL; 51 | t->flag = 0; 52 | return t; 53 | } 54 | 55 | //向节点插入数据 56 | tree insert_tree(tree t, int v) { 57 | if (!t) 58 | t = new_node(v); //如果是一棵空树,那么创建一个新节点作为树根 59 | else { 60 | if (v > t->v) { 61 | t->right = insert_tree(t->right, v); 62 | } else { 63 | t->left = insert_tree(t->left, v); 64 | } 65 | } 66 | return t; 67 | } 68 | 69 | //创建一棵搜索树 70 | tree make_tree(int n) { 71 | tree t; 72 | int i, v; 73 | 74 | scanf("%d", &v); 75 | 76 | t = new_node(v); 77 | for (i = 1; i < n; i++) { 78 | scanf("%d", &v); 79 | t = insert_tree(t, v); 80 | } 81 | return t; 82 | } 83 | 84 | //在树t中搜索整数v,看看v是否符合要求 85 | int check(tree t, int v) { 86 | if (t->flag) { 87 | if (v < t->v) 88 | return check(t->left, v); 89 | else if (v > t->v) 90 | return check(t->right, v); 91 | } else { 92 | if (v == t->v) { 93 | t->flag = 1; 94 | return 1; 95 | } else { 96 | return 0; 97 | } 98 | 99 | } 100 | } 101 | 102 | //判断一组数据插入后是否和树t相同,返回1则相同,返回0则不相同 103 | //判断flag的原因是,即使已经知道不一致了,但是如果不继续将后面的数据输入,会导致程序错误 104 | int judge(tree t, int n) { 105 | int i, v, flag = 0; 106 | scanf("%d", &v); 107 | if (v != t->v) //如果树根不相等,直接返回0,即不同 108 | flag = 1; 109 | else 110 | t->flag = 1; //这个节点比较过 111 | 112 | for (i = 1; i < n; i++) { 113 | scanf("%d", &v); 114 | if ((!flag) && !check(t, v)) 115 | flag = 1; 116 | } 117 | 118 | if (flag) 119 | return 0; 120 | else 121 | return 1; 122 | } 123 | 124 | void reset_tree(tree t) { 125 | if (t->left) 126 | reset_tree(t->left); 127 | if (t->right) 128 | reset_tree(t->right); 129 | t->flag = 0; 130 | } 131 | 132 | void free_tree(tree t) { 133 | if (t->left) 134 | free_tree(t->left); 135 | if (t->right) 136 | free_tree(t->right); 137 | free(t); 138 | } 139 | 140 | /* 141 | 读入 n 和 l 142 | 根据第一行序列建立树T 143 | 依据树T分别判断后面的L个序列是否能与T形成同一搜索树并输出结果 144 | 如何判别序列是否与树是一致的呢? 145 | 方法:在树T中按顺序搜索序列中的每个数 146 | - 如果每次搜索所经过的节点在前面均为出现过,则一致 147 | - 否则,如果某次搜索中遇到前面未出现的节点,则不一致 148 | */ 149 | int main() { 150 | int n, l, i; 151 | tree t; 152 | 153 | scanf("%d", &n); //输入后面每个序列的节点数 154 | 155 | while (n) { 156 | scanf("%d", &l); //获得后面有几组数据,然后分别判定每一组数据 157 | t = make_tree(n); 158 | for (i = 0; i < l; i++) { 159 | if (judge(t, n)) { 160 | printf("Yes\n"); 161 | } else { 162 | printf("No\n"); 163 | } 164 | reset_tree(t); 165 | } 166 | free_tree(t); 167 | scanf("%d", &n); //读入下一个N也就是下一组数据的节点个数,开启下一个循环 168 | } 169 | 170 | return 0; 171 | } 172 | 173 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/04_5_Root_of_AVL_Tree.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Root_of_AVL_Tree.cpp 3 | * 4 | * Created on: 2018年4月18日 5 | * Author: Administrator 6 | */ 7 | 8 | /* 9 | 04-树5 Root of AVL Tree(25 分) 10 | An AVL tree is a self-balancing binary search tree. 11 | In an AVL tree, the heights of the two child subtrees of any node differ by at most one; 12 | if at any time they differ by more than one, rebalancing is done to restore this property. 13 | Figures 1-4 illustrate the rotation rules. 14 | 15 | Now given a sequence of insertions, you are supposed to tell the root of the resulting AVL tree. 16 | Input Specification: 17 | 18 | Each input file contains one test case. For each case, 19 | the first line contains a positive integer N (≤20) which is the total number of keys to be inserted. 20 | Then N distinct integer keys are given in the next line. 21 | All the numbers in a line are separated by a space. 22 | 23 | Output Specification: 24 | 25 | For each test case, print the root of the resulting AVL tree in one line. 26 | 27 | Sample Input 1: 28 | 29 | 5 30 | 88 70 61 96 120 31 | Sample Output 1: 32 | 33 | 70 34 | Sample Input 2: 35 | 36 | 7 37 | 88 70 61 96 120 90 65 38 | Sample Output 2: 39 | 40 | 88 41 | 42 | 题目翻译: 43 | 44 | 一个平衡二叉树是一个自平衡的二叉查找树。在一个平衡二叉树中,任何节点的两个子树的高度差最多为1。 45 | 任何时候平衡因子大于 1 的时候,那么重新平衡这棵树就可以恢复平衡二叉树的特性。 46 | 47 | 现在给你一组插入值,你应该给出平衡二叉搜索树的根。 48 | 49 | 输入格式: 50 | 每一个文件包含一个测试点,对于每个测试,第一行给出一个正数值说明有多少个插入点。 51 | 然后 N 个插入点的正数值会在下一行给出,所有在一行的数字都被空格隔开。 52 | 53 | 输出格式: 54 | 对于每一个测试点,打在一行中打印出平衡二叉搜索树的根。 55 | 56 | Sample Input 1: 57 | 58 | 5 59 | 88 70 61 96 120 60 | Sample Output 1: 61 | 62 | 70 63 | Sample Input 2: 64 | 65 | 7 66 | 88 70 61 96 120 90 65 67 | Sample Output 2: 68 | 69 | 88 70 | */ 71 | 72 | #include 73 | #include 74 | 75 | typedef struct ALVNode *AVLTree; 76 | typedef struct ALVNode *Position; 77 | struct ALVNode{ 78 | int Data; 79 | int Height; 80 | AVLTree Left; 81 | AVLTree Right; 82 | }; 83 | 84 | AVLTree Insert(int X, AVLTree T); 85 | int GetHeight(Position T); 86 | int Max(int a, int b); 87 | Position SingleLeft(Position K); 88 | Position SingleRight(Position K); 89 | Position DoubleLeft(Position K); 90 | Position DoubleRight(Position K); 91 | 92 | int GetHeight(Position T) { 93 | if (!T) { 94 | return -1; 95 | } else { 96 | return T->Height; 97 | } 98 | } 99 | 100 | int Max(int a, int b) { 101 | return (a > b) ? a : b; 102 | } 103 | 104 | Position SingleLeft(Position K) { 105 | Position Tmp; 106 | Tmp = K; 107 | K = K->Left; 108 | Tmp->Left = K->Right; 109 | K->Right = Tmp; 110 | Tmp->Height = Max(GetHeight(Tmp->Left), GetHeight(Tmp->Right)) + 1; 111 | K->Height = Max(GetHeight(K->Left), GetHeight(K->Right)) + 1; 112 | return K; 113 | } 114 | 115 | Position SingleRight(Position K) { 116 | Position Tmp; 117 | Tmp = K; 118 | K = K->Right; 119 | Tmp->Right = K->Left; 120 | K->Left = Tmp; 121 | Tmp->Height = Max(GetHeight(Tmp->Left), GetHeight(Tmp->Right)) + 1; 122 | K->Height = Max(GetHeight(K->Left), GetHeight(K->Right)) + 1; 123 | return K; 124 | } 125 | 126 | Position DoubleLeft(Position K) { 127 | K->Left = SingleRight(K->Left); 128 | return SingleLeft(K); 129 | } 130 | 131 | Position DoubleRight(Position K) { 132 | K->Right = SingleLeft(K->Right); 133 | return SingleRight(K); 134 | } 135 | 136 | AVLTree Insert(int X, AVLTree T) { 137 | if (T == NULL) { 138 | T = (AVLTree) malloc(sizeof(struct ALVNode)); 139 | T->Data = X; 140 | T->Height = 0; 141 | T->Left = T->Right = NULL; 142 | } else if (X < T->Data) { 143 | T->Left = Insert(X, T->Left); 144 | if (GetHeight(T->Left) - GetHeight(T->Right) == 2) { 145 | if (X < T->Left->Data) 146 | T = SingleLeft(T); 147 | else 148 | T = DoubleLeft(T); 149 | } 150 | } else if (X > T->Data) { 151 | T->Right = Insert(X, T->Right); 152 | if (GetHeight(T->Right) - GetHeight(T->Left) == 2) { 153 | if (X > T->Right->Data) 154 | T = SingleRight(T); 155 | else 156 | T = DoubleRight(T); 157 | } 158 | } 159 | T->Height = Max(GetHeight(T->Left), GetHeight(T->Right)) + 1; 160 | return T; 161 | } 162 | 163 | /* 164 | int main() { 165 | AVLTree T = NULL; 166 | int n; 167 | scanf("%d", &n); 168 | while (n--) { 169 | int x; 170 | scanf("%d", &x); 171 | T = Insert(x, T); 172 | } 173 | if (T) { 174 | printf("%d", T->Data); 175 | } 176 | 177 | return 0; 178 | } 179 | */ 180 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/04_6_Complete_Binary_Search_Tree.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 04_6_Complete_Binary_Search_Tree.cpp 3 | * 4 | * Created on: 2018年5月14日 5 | * Author: SummerGift 6 | */ 7 | 8 | /* 9 | * 10 | 04-树6 Complete Binary Search Tree(30 分) 11 | A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties: 12 | 13 | The left subtree of a node contains only nodes with keys less than the node's key. 14 | The right subtree of a node contains only nodes with keys greater than or equal to the node's key. 15 | Both the left and right subtrees must also be binary search trees. 16 | A Complete Binary Tree (CBT) is a tree that is completely filled, 17 | with the possible exception of the bottom level, which is filled from left to right. 18 | 19 | Now given a sequence of distinct non-negative integer keys, 20 | a unique BST can be constructed if it is required that the tree must also be a CBT. 21 | You are supposed to output the level order traversal sequence of this BST. 22 | 23 | Input Specification: 24 | Each input file contains one test case. For each case, 25 | the first line contains a positive integer N (≤1000). 26 | Then N distinct non-negative integer keys are given in the next line. 27 | All the numbers in a line are separated by a space and are no greater than 2000. 28 | 29 | Output Specification: 30 | For each test case, print in one line the level order traversal sequence of the corresponding complete binary search tree. 31 | All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line. 32 | 33 | Sample Input: 34 | 10 35 | 1 2 3 4 5 6 7 8 9 0 36 | Sample Output: 37 | 6 3 8 1 5 7 9 0 2 4 38 | 39 | */ 40 | 41 | #include 42 | #include 43 | 44 | int tree_array[1005]; 45 | int j = 0; 46 | 47 | int compare(const void *a, const void *b); 48 | void mid_tree(int root, int n, int a[]); 49 | 50 | int compare(const void *a, const void *b) { 51 | return *(int *) a - *(int *) b; 52 | } 53 | 54 | //递归实现查找根节点,并且将根节点依次存放到 tree_array 数组中 55 | void mid_tree(int root, int N, int a[]) { 56 | if (root <= N) { 57 | mid_tree(2 * root, N, a); 58 | tree_array[root] = a[j++]; 59 | mid_tree(2 * root + 1, N, a); 60 | } 61 | } 62 | 63 | /* 64 | int main() { 65 | int N; 66 | scanf("%d", &N); 67 | int input_array[N]; 68 | 69 | for (int i = 0; i <= N; i++) { 70 | scanf("%d", &input_array[i]); 71 | } 72 | 73 | qsort(input_array, N, sizeof(int), compare); 74 | 75 | mid_tree(1, N, input_array); 76 | 77 | printf("%d", tree_array[1]); 78 | 79 | for (int j = 2; j <= N; j++) { 80 | printf(" %d", tree_array[j]); 81 | } 82 | } 83 | */ 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/04_7_Binarysearch_tree_operation_set.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 04_7_Binarysearch_tree_operation_set.cpp 3 | * 4 | * Created on: 2018年5月1日 5 | * Author: SummerGift 6 | */ 7 | #include 8 | #include 9 | 10 | typedef int ElementType; 11 | 12 | typedef struct TNode *Position; 13 | typedef Position BinTree; 14 | struct TNode{ 15 | ElementType Data; 16 | BinTree Left; 17 | BinTree Right; 18 | }; 19 | 20 | BinTree Insert( BinTree BST, ElementType X ); 21 | BinTree Delete( BinTree BST, ElementType X ); 22 | Position Find( BinTree BST, ElementType X ); 23 | Position FindMin( BinTree BST ); 24 | Position FindMax( BinTree BST ); 25 | 26 | Position FindMin(BinTree BST) { 27 | if (!BST) 28 | return NULL; 29 | else if (!BST->Left) 30 | return BST; 31 | else 32 | return FindMin(BST->Left); 33 | } 34 | 35 | Position FindMax(BinTree BST) { 36 | if (BST) { 37 | while (BST->Right) 38 | BST = BST->Right; 39 | } 40 | return BST; 41 | } 42 | 43 | BinTree Insert(BinTree BST, ElementType X) { 44 | if (!BST) { 45 | BST = (BinTree) malloc(sizeof(struct TNode)); 46 | BST->Data = X; 47 | BST->Left = BST->Right = NULL; 48 | } else { 49 | if (X < BST->Data) 50 | BST->Left = Insert(BST->Left, X); 51 | else if (X > BST->Data) 52 | BST->Right = Insert(BST->Right, X); 53 | } 54 | return BST; 55 | } 56 | 57 | BinTree Delete(BinTree BST, ElementType X) { 58 | Position tmp; 59 | 60 | if (!BST) { 61 | printf("Not Found\n"); 62 | } else { 63 | if (X < BST->Data) 64 | BST->Left = Delete(BST->Left, X); 65 | else if (X > BST->Data) 66 | BST->Right = Delete(BST->Right, X); 67 | else { 68 | if (BST->Left && BST->Right) { 69 | tmp = FindMin(BST->Right); 70 | BST->Data = tmp->Data; 71 | BST->Right = Delete(BST->Right, BST->Data); 72 | } else { 73 | tmp = BST; //处理基本情况,也就是只有一个子节点或者没有子节点的情况 74 | if (!BST->Left) { 75 | BST = BST->Right; 76 | } else { 77 | BST = BST->Left; 78 | } 79 | free(tmp); 80 | } 81 | } 82 | } 83 | return BST; 84 | } 85 | 86 | Position Find(BinTree BST, ElementType X) { 87 | while (BST) { 88 | if (X > BST->Data) 89 | BST = BST->Right; 90 | else if (X < BST->Data) 91 | BST = BST->Left; 92 | else 93 | return BST; 94 | } 95 | return NULL; 96 | } 97 | 98 | 99 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/05_7_heap_path.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 05_7_heap_path.cpp 3 | * 4 | * Created on: 2018年5月16日 5 | * Author: SummerGift 6 | */ 7 | 8 | /* 9 | 05-树7 堆中的路径(25 分) 10 | 将一系列给定数字插入一个初始为空的小顶堆H[]。随后对任意给定的下标i,打印从H[i]到根结点的路径。 11 | 12 | 输入格式: 13 | 每组测试第1行包含2个正整数N和M(≤1000),分别是插入元素的个数、以及需要打印的路径条数。 14 | 下一行给出区间[-10000, 10000]内的N个要被插入一个初始为空的小顶堆的整数。 15 | 最后一行给出M个下标。 16 | 17 | 输出格式: 18 | 对输入中给出的每个下标i,在一行中输出从H[i]到根结点的路径上的数据。数字间以1个空格分隔,行末不得有多余空格。 19 | 20 | 输入样例: 21 | 5 3 22 | 46 23 26 24 10 23 | 5 4 3 24 | 25 | 输出样例: 26 | 24 23 10 27 | 46 23 10 28 | 26 10 29 | */ 30 | 31 | #include 32 | #define MAX_NUM_HEAP 1001 33 | #define MIN_VALUE -10001 34 | 35 | int heap[MAX_NUM_HEAP], size; 36 | 37 | void create_heap(int *heap, int *heap_size) { 38 | *heap_size = 0; 39 | heap[0] = MIN_VALUE; 40 | } 41 | 42 | void heap_insert(int x) { 43 | int i; 44 | for (i = ++size; heap[i / 2] > x; i /= 2) 45 | heap[i] = heap[i / 2]; 46 | heap[i] = x; 47 | } 48 | 49 | int main() { 50 | int n, m, x, i, output_index; 51 | 52 | scanf("%d %d", &n, &m); 53 | 54 | create_heap(heap, &size); 55 | for (i = 0; i < n; i++) { 56 | scanf("%d", &x); 57 | heap_insert(x); 58 | } 59 | 60 | for (i = 0; i < m; i++) { 61 | scanf("%d", &output_index); 62 | printf("%d", heap[output_index]); 63 | while (output_index > 1) { 64 | output_index /= 2; 65 | printf(" %d", heap[output_index]); 66 | } 67 | printf("\n"); 68 | } 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/05_8_File_Transfer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 05_8_File_Transfer.cpp 3 | * 4 | * Created on: 2018年5月21日 5 | * Author: Administrator 6 | */ 7 | 8 | /* 9 | 05-树8 File Transfer(25 分) 10 | We have a network of computers and a list of bi-directional connections. 11 | Each of these connections allows a file transfer from one computer to another. 12 | Is it possible to send a file from any computer on the network to any other? 13 | 14 | Input Specification: 15 | 16 | Each input file contains one test case. For each test case, the first line contains N (2≤N≤10^4), 17 | the total number of computers in a network. 18 | Each computer in the network is then represented by a positive integer between 1 and N. 19 | Then in the following lines, the input is given in the format: 20 | 21 | I c1 c2 22 | where I stands for inputting a connection between c1 and c2; or 23 | 24 | C c1 c2 25 | where C stands for checking if it is possible to transfer files between c1 and c2; or 26 | 27 | S 28 | 29 | where S stands for stopping this case. 30 | 31 | Output Specification: 32 | 33 | For each C case, print in one line the word "yes" or "no" if it is possible or impossible to transfer files between c1 and c2, 34 | respectively. At the end of each case, print in one line "The network is connected." 35 | if there is a path between any pair of computers; or "There are k components." 36 | where k is the number of connected components in this network. 37 | 38 | Sample Input 1: 39 | 40 | 5 41 | C 3 2 42 | I 3 2 43 | C 1 5 44 | I 4 5 45 | I 2 4 46 | C 3 5 47 | S 48 | Sample Output 1: 49 | 50 | no 51 | no 52 | yes 53 | There are 2 components. 54 | Sample Input 2: 55 | 56 | 5 57 | C 3 2 58 | I 3 2 59 | C 1 5 60 | I 4 5 61 | I 2 4 62 | C 3 5 63 | I 1 3 64 | C 1 5 65 | S 66 | Sample Output 2: 67 | 68 | no 69 | no 70 | yes 71 | yes 72 | The network is connected. 73 | */ 74 | #include 75 | #include 76 | 77 | typedef int element_type; 78 | typedef int root_index; 79 | typedef int* root_type; 80 | 81 | //在本题中,关于集合的表示方法可以被简化,可以将N个元素映射到 0 - (N-1) 下标的数组中, 82 | //这样就不用像一般表示法那样遍历整个数组来寻找元素所在的位置 83 | //查找元素x所在位置的值,如果不是复数,那么就查找这个值对应位置的值,直到找到根结点所在的位置 84 | root_index find(root_type S, element_type X) { 85 | for (; S[X] >= 0; X = S[X]) 86 | ; 87 | return X; 88 | } 89 | 90 | void union_root(root_type S, root_index root1, root_index root2) { 91 | S[root1] = root2; 92 | } 93 | 94 | void senior_union_root(root_type S, root_index root1, root_index root2) { 95 | if (S[root2] < S[root1]) // root2 更深 96 | S[root1] = root2; // 将 root2 作为合并后的新根 97 | else { 98 | if (S[root2] == S[root1]) 99 | S[root1]--; // 两棵树深度相同,选择一颗深度+1 100 | S[root2] = root1; // 合并 101 | } 102 | } 103 | 104 | void initialization(root_type S, int n) { 105 | for (int i = 0; i < n; i++) 106 | S[i] = -1; 107 | } 108 | 109 | void input_connection(root_type S) { 110 | element_type u, v; 111 | root_index root1, root2; 112 | scanf("%d %d\n", &u, &v); 113 | root1 = find(S, u - 1); 114 | root2 = find(S, v - 1); 115 | if (root1 != root2) 116 | senior_union_root(S, root1, root2); 117 | } 118 | 119 | void check_connection(root_type S) { 120 | element_type u, v; 121 | root_index root1, root2; 122 | scanf("%d %d\n", &u, &v); 123 | root1 = find(S, u - 1); //这里-1 是因为第u个元素在数组中的位置为u - 1 124 | root2 = find(S, v - 1); 125 | if (root1 == root2) 126 | printf("yes\n"); 127 | else 128 | printf("no\n"); 129 | } 130 | 131 | void check_network(root_type S, int n) { 132 | int i, counter = 0; 133 | for (i = 0; i < n; i++) { 134 | if (S[i] < 0) 135 | counter++; 136 | } 137 | 138 | if (counter == 1) 139 | printf("The network is connected.\n"); 140 | else 141 | printf("There are %d components.\n", counter); 142 | } 143 | 144 | int main() { 145 | int *S; 146 | int n; 147 | char input_char; 148 | scanf("%d\n", &n); 149 | S = (int*) malloc(sizeof(int) * n); 150 | initialization(S, n); 151 | do { 152 | scanf("%c", &input_char); 153 | switch (input_char) { 154 | case 'I': 155 | input_connection(S); 156 | break; 157 | case 'C': 158 | check_connection(S); 159 | break; 160 | case 'S': 161 | check_network(S, n); 162 | break; 163 | } 164 | } while (input_char != 'S'); 165 | free(S); 166 | return 0; 167 | } 168 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/05_9_Huffman_Codes.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 05_9_Huffman_Codes.cpp 3 | * 4 | * Created on: 2018年5月27日 5 | * Author: SummerGift 6 | */ 7 | /* 8 | 9 | 05-树9 Huffman Codes(30 分) 10 | In 1953, David A. Huffman published his paper "A Method for the Construction of Minimum-Redundancy Codes", 11 | and hence printed his name in the history of computer science. 12 | As a professor who gives the final exam problem on Huffman codes, 13 | I am encountering a big problem: the Huffman codes are NOT unique. 14 | For example, given a string "aaaxuaxz", we can observe that the frequencies of the characters 'a', 'x', 'u' and 'z' are 4, 2, 1 and 1, 15 | respectively. We may either encode the symbols as {'a'=0, 'x'=10, 'u'=110, 'z'=111}, or in another way as {'a'=1, 'x'=01, 'u'=001, 'z'=000}, 16 | both compress the string into 14 bits. 17 | Another set of code can be given as {'a'=0, 'x'=11, 'u'=100, 'z'=101}, 18 | but {'a'=0, 'x'=01, 'u'=011, 'z'=001}is NOT correct since "aaaxuaxz" and "aazuaxax" can both be decoded from the code 00001011001001. 19 | The students are submitting all kinds of codes, and I need a computer program to help me determine which ones are correct and which ones are not. 20 | 21 | Input Specification: 22 | Each input file contains one test case. For each case, 23 | the first line gives an integer N (2≤N≤63), then followed by a line that contains all the N distinct characters and their frequencies in the following format: 24 | 25 | c[1] f[1] c[2] f[2] ... c[N] f[N] 26 | where c[i] is a character chosen from {'0' - '9', 'a' - 'z', 'A' - 'Z', '_'}, 27 | and f[i] is the frequency of c[i] and is an integer no more than 1000. 28 | The next line gives a positive integer M (≤1000), then followed by M student submissions. 29 | Each student submission consists of N lines, each in the format: 30 | 31 | c[i] code[i] 32 | where c[i] is the i-th character and code[i] is an non-empty string of no more than 63 '0's and '1's. 33 | 34 | Output Specification: 35 | For each test case, print in each line either "Yes" if the student's submission is correct, or "No" if not. 36 | 37 | Note: The optimal solution is not necessarily generated by Huffman algorithm. 38 | Any prefix code with code length being optimal is considered correct. 39 | 40 | Sample Input: 41 | 7 42 | A 1 B 1 C 1 D 3 E 3 F 6 G 6 43 | 4 44 | A 00000 45 | B 00001 46 | C 0001 47 | D 001 48 | E 01 49 | F 10 50 | G 11 51 | A 01010 52 | B 01011 53 | C 0100 54 | D 011 55 | E 10 56 | F 11 57 | G 00 58 | A 000 59 | B 001 60 | C 010 61 | D 011 62 | E 100 63 | F 101 64 | G 110 65 | A 00000 66 | B 00001 67 | C 0001 68 | D 001 69 | E 00 70 | F 10 71 | G 11 72 | Sample Output: 73 | Yes 74 | Yes 75 | No 76 | No 77 | 78 | 这道题的意思是给出一组字符和出现的频率,让我们构造他们的哈夫曼编码。 79 | 由于哈夫曼编码不唯一,所以编码方式有多种。然后有M个同学给出了他们的编码方式, 80 | 让我们判断他们的编码是否正确。正确输出Yes,错误输出No 81 | 82 | 问题可以分成两部分: 83 | 1.构造N个字符的哈夫曼编码,计算带权路径长度WPL,判断每个同学的编码带权路径长度是否 84 | 等于之前计算出来的WPL. 85 | 2.判断是否有某一个字符的编码是另一个字符的前缀码。 86 | 87 | */ 88 | 89 | #include 90 | #include 91 | #include 92 | #include 93 | 94 | #define MAX_N 64 95 | #define YES 1 96 | #define NO 0 97 | #define MIN_DATA -1 98 | #define QUEUE_SIZE 100 99 | 100 | typedef struct tree_node *tree_node_t; 101 | struct tree_node { 102 | int weight; 103 | tree_node_t left, right; 104 | }; 105 | 106 | //构建最小堆 107 | struct heap_struct { 108 | tree_node_t data; 109 | int size; 110 | int capacity; 111 | }; 112 | typedef struct heap_struct *min_heap_t; 113 | 114 | struct queue_node { 115 | tree_node_t data[QUEUE_SIZE]; 116 | int rear; 117 | int front; 118 | }; 119 | typedef struct queue_node *queue_node_t; 120 | 121 | //创建最小堆 122 | min_heap_t create_min_heap(int max_size) 123 | { 124 | min_heap_t h = (min_heap_t)malloc(sizeof(struct heap_struct)); 125 | h->data = (tree_node_t)malloc(sizeof(struct tree_node)*(max_size + 1)); 126 | h->size = 0; 127 | h->capacity = max_size; 128 | h->data[0].weight = MIN_DATA; 129 | return h; 130 | } 131 | 132 | //先接收输入的需要编码的数据,然后按照最优编码方式进行编码,计算最优的WPL 133 | //分别接收学生们的编码,查看学生们的编码是否是最优编码,以及是否正确,如果正确返回Yes,错误返回No 134 | 135 | min_heap_t get_data_to_heap(int number, char *ch, int *cf, min_heap_t H); 136 | tree_node_t build_huffman_tree(min_heap_t H); 137 | int count_wpl(tree_node_t H, int depth); 138 | int judge_tree(int input_count, int codelen, char *ch, int *cf); 139 | 140 | int main() { 141 | int input_count, code_len, n; 142 | 143 | min_heap_t min_heap; 144 | char *ch; 145 | int *cf; 146 | tree_node_t huffman_tree; 147 | scanf("%d\n", &input_count); 148 | printf("the input_cont is %d", input_count); 149 | 150 | //创建最小堆并将后面的数据读入最小堆 151 | min_heap = create_min_heap(input_count); 152 | ch = (char *) malloc(sizeof(char) * input_count); 153 | cf = (int *) malloc(sizeof(int) * input_count); 154 | min_heap = get_data_to_heap(input_count, ch, cf, min_heap); 155 | 156 | //将最小堆输入进来并创建哈夫曼树 157 | huffman_tree = build_huffman_tree(min_heap); 158 | 159 | //计算 WPL 160 | code_len = count_wpl(huffman_tree, 0); 161 | 162 | //判断 n 组数据是否为最优编码并符合条件。符合的打印yes, 不符合打印 no。 163 | scanf("%d\n", &n); 164 | for (int i = 0; i < n; i++) { 165 | if (judge_tree(input_count, code_len, ch, cf)) 166 | printf("Yes\n"); 167 | else 168 | printf("No\n"); 169 | } 170 | 171 | return 0; 172 | } 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/C_advanced/dlist.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dlist.c 3 | * Author: Li XianJing 4 | * Brief: double list implementation. 5 | * 6 | * Copyright (c) Li XianJing 7 | * 8 | * Licensed under the Academic Free License version 2.1 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | 25 | /* 26 | * History: 27 | * ================================================================ 28 | * 2008-11-09 Li XianJing created 29 | * 30 | */ 31 | #include 32 | #include "dlist.h" 33 | 34 | typedef struct _DListNode 35 | { 36 | struct _DListNode* prev; 37 | struct _DListNode* next; 38 | 39 | void* data; //通用链表在存储数据的时候只保存数据的指针,这样不用复制数据效率高 40 | }DListNode; 41 | 42 | struct _DList 43 | { 44 | DListNode* first; 45 | }; 46 | 47 | static DListNode* dlist_node_create(void* data) 48 | { 49 | DListNode* node = malloc(sizeof(DListNode)); 50 | 51 | if(node != NULL) 52 | { 53 | node->prev = NULL; 54 | node->next = NULL; 55 | node->data = data; 56 | } 57 | 58 | return node; 59 | } 60 | 61 | static void dlist_node_destroy(DListNode* node) 62 | { 63 | if(node != NULL) 64 | { 65 | node->next = NULL; 66 | node->prev = NULL; 67 | free(node); 68 | } 69 | 70 | return; 71 | } 72 | 73 | DList* dlist_create(void) 74 | { 75 | DList* thiz = malloc(sizeof(DList)); 76 | 77 | if(thiz != NULL) 78 | { 79 | thiz->first = NULL; 80 | } 81 | 82 | return thiz; 83 | } 84 | 85 | static DListNode* dlist_get_node(DList* thiz, size_t index, int fail_return_last) 86 | { 87 | DListNode* iter = thiz->first; 88 | 89 | while(iter != NULL && iter->next != NULL && index > 0) 90 | { 91 | iter = iter->next; 92 | index--; 93 | } 94 | 95 | if(!fail_return_last) 96 | { 97 | iter = index > 0 ? NULL : iter; 98 | } 99 | 100 | return iter; 101 | } 102 | 103 | DListRet dlist_insert(DList* thiz, size_t index, void* data) 104 | { 105 | DListNode* node = NULL; 106 | DListNode* cursor = NULL; 107 | 108 | if((node = dlist_node_create(data)) == NULL) 109 | { 110 | return DLIST_RET_OOM; 111 | } 112 | 113 | if(thiz->first == NULL) 114 | { 115 | thiz->first = node; 116 | 117 | return DLIST_RET_OK; 118 | } 119 | 120 | cursor = dlist_get_node(thiz, index, 1); 121 | 122 | if(index < dlist_length(thiz)) 123 | { 124 | if(thiz->first == cursor) 125 | { 126 | thiz->first = node; 127 | } 128 | else 129 | { 130 | cursor->prev->next = node; 131 | node->prev = cursor->prev; 132 | } 133 | node->next = cursor; 134 | cursor->prev = node; 135 | } 136 | else 137 | { 138 | cursor->next = node; 139 | node->prev = cursor; 140 | } 141 | 142 | return DLIST_RET_OK; 143 | } 144 | 145 | DListRet dlist_prepend(DList* thiz, void* data) 146 | { 147 | return dlist_insert(thiz, 0, data); 148 | } 149 | 150 | DListRet dlist_append(DList* thiz, void* data) 151 | { 152 | return dlist_insert(thiz, -1, data); 153 | } 154 | 155 | DListRet dlist_delete(DList* thiz, size_t index) 156 | { 157 | DListNode* cursor = dlist_get_node(thiz, index, 0); 158 | 159 | if(cursor != NULL) 160 | { 161 | if(cursor == thiz->first) 162 | { 163 | thiz->first = cursor->next; 164 | } 165 | 166 | if(cursor->next != NULL) 167 | { 168 | cursor->next->prev = cursor->prev; 169 | } 170 | 171 | if(cursor->prev != NULL) 172 | { 173 | cursor->prev->next = cursor->next; 174 | } 175 | 176 | dlist_node_destroy(cursor); 177 | } 178 | 179 | return DLIST_RET_OK; 180 | } 181 | 182 | DListRet dlist_get_by_index(DList* thiz, size_t index, void** data) 183 | { 184 | DListNode* cursor = dlist_get_node(thiz, index, 0); 185 | 186 | if(cursor != NULL) 187 | { 188 | *data = cursor->data; 189 | } 190 | 191 | return cursor != NULL ? DLIST_RET_OK : DLIST_RET_FAIL; 192 | } 193 | 194 | DListRet dlist_set_by_index(DList* thiz, size_t index, void* data) { 195 | DListNode* cursor = dlist_get_node(thiz, index, 0); 196 | 197 | if (cursor != NULL) { 198 | cursor->data = data; 199 | } 200 | 201 | return cursor != NULL ? DLIST_RET_OK : DLIST_RET_FAIL; 202 | } 203 | 204 | size_t dlist_length(DList* thiz) { 205 | size_t length = 0; 206 | DListNode* iter = thiz->first; 207 | 208 | while (iter != NULL) { 209 | length++; 210 | iter = iter->next; 211 | } 212 | 213 | return length; 214 | } 215 | 216 | DListRet dlist_print(DList* thiz, DListDataPrintFunc print) 217 | { 218 | DListRet ret = DLIST_RET_OK; 219 | DListNode* iter = thiz->first; 220 | 221 | while(iter != NULL) 222 | { 223 | print(iter->data); 224 | 225 | iter = iter->next; 226 | } 227 | 228 | return ret; 229 | } 230 | 231 | void dlist_destroy(DList* thiz) 232 | { 233 | DListNode* iter = thiz->first; 234 | DListNode* next = NULL; 235 | 236 | while(iter != NULL) 237 | { 238 | next = iter->next; 239 | dlist_node_destroy(iter); 240 | iter = next; 241 | } 242 | 243 | thiz->first = NULL; 244 | free(thiz); 245 | 246 | return; 247 | } 248 | 249 | #include 250 | #include 251 | #include "dlist.h" 252 | 253 | static DListRet print_int(void* data) 254 | { 255 | printf("%d ", (int)data); 256 | 257 | return DLIST_RET_OK; 258 | } 259 | 260 | int main(int argc, char* argv[]) 261 | { 262 | int i = 0; 263 | int n = 100; 264 | DList* dlist = dlist_create(); 265 | 266 | for(i = 0; i < n; i++) 267 | { 268 | assert(dlist_append(dlist, (void*)i) == DLIST_RET_OK); 269 | } 270 | for(i = 0; i < n; i++) 271 | { 272 | assert(dlist_prepend(dlist, (void*)i) == DLIST_RET_OK); 273 | } 274 | 275 | dlist_print(dlist, print_int); 276 | 277 | dlist_destroy(dlist); 278 | 279 | return 0; 280 | } 281 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/C_advanced/dlist.h: -------------------------------------------------------------------------------- 1 | #ifndef DLIST_H 2 | #define DLIST_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif/*__cplusplus*/ 7 | 8 | typedef enum _DListRet 9 | { 10 | DLIST_RET_OK, 11 | DLIST_RET_OOM, 12 | DLIST_RET_STOP, 13 | DLIST_RET_PARAMS, 14 | DLIST_RET_FAIL 15 | }DListRet; 16 | 17 | struct _DList; 18 | typedef struct _DList DList; 19 | 20 | typedef DListRet (*DListDataPrintFunc)(void* data); 21 | 22 | DList* dlist_create(void); 23 | 24 | DListRet dlist_insert(DList* thiz, size_t index, void* data); 25 | DListRet dlist_prepend(DList* thiz, void* data); 26 | DListRet dlist_append(DList* thiz, void* data); 27 | DListRet dlist_delete(DList* thiz, size_t index); 28 | DListRet dlist_get_by_index(DList* thiz, size_t index, void** data); 29 | DListRet dlist_set_by_index(DList* thiz, size_t index, void* data); 30 | size_t dlist_length(DList* thiz); 31 | DListRet dlist_print(DList* thiz, DListDataPrintFunc print); 32 | 33 | void dlist_destroy(DList* thiz); 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif/*__cplusplus*/ 38 | 39 | #endif/*DLIST*/ 40 | 41 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/Project_01_recursive_function.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | typedef int ElementType; 7 | typedef struct Node *PtrToNode; 8 | struct Node { 9 | ElementType Data; 10 | PtrToNode Next; 11 | }; 12 | typedef PtrToNode List; 13 | 14 | using namespace std; 15 | 16 | //递归求和 17 | unsigned int sum(int n) { 18 | if (n > 1) 19 | return n + sum(n - 1); 20 | else if (n == 1) { 21 | return 1; 22 | } 23 | } 24 | 25 | //求斐波那契数列的第N个值 26 | unsigned int fac(int n) { 27 | if (n >= 3) { 28 | return fac(n - 1) + fac(n - 2); 29 | } 30 | 31 | if (n == 2) 32 | return 1; 33 | 34 | if (n == 1) 35 | return 1; 36 | } 37 | 38 | //求字符串的长度 39 | unsigned int get_strlen(char *s) { 40 | if (*s != '\0') 41 | return 1 + get_strlen(s + 1); 42 | if (*s == '\0') 43 | return 0; 44 | } 45 | 46 | //链表的反转 47 | List reverse(List list) { 48 | if ((list == NULL || list->Next == NULL)) { 49 | return list; 50 | } else { 51 | List guard = list->Next; 52 | List ret = reverse(list->Next); 53 | guard->Next = list; 54 | list->Next = NULL; 55 | return ret; 56 | } 57 | } 58 | 59 | //有序链表的合并 60 | List List_Merge(List L1, List L2) { 61 | if (L1 == NULL) { 62 | return L2; 63 | } else if (L2 == NULL) { 64 | return L1; 65 | } else if (L1->Data <= L2->Data) { 66 | List list_1 = L1->Next; 67 | List list = List_Merge(list_1, L2); 68 | L1->Next = list; 69 | return L1; 70 | } else { 71 | List list_2 = L2->Next; 72 | List list = List_Merge(list_2, L1); 73 | L2->Next = list; 74 | return L2; 75 | } 76 | } 77 | 78 | //汉诺塔问题 从 a 到 c, b 为中转站 79 | void HanoiTower(int n, char a, char b, char c) { 80 | if (n == 1) { 81 | cout << a << "-->" << c << endl; 82 | } else { 83 | HanoiTower(n - 1, a, c, b); 84 | HanoiTower(1, a, b, c); 85 | HanoiTower(n - 1, b, a, c); 86 | } 87 | } 88 | 89 | //全排列问题 90 | void permutation(char *s, char *e) { 91 | if (*s == '\0') { 92 | cout << e << endl; 93 | } else { 94 | int len = strlen(s); 95 | 96 | for (int i = 0; i < len; i++) { 97 | if ((i == 0) || (s[0] != s[i])) { 98 | swap(s[0], s[i]); 99 | permutation(s + 1, e); 100 | swap(s[0], s[i]); 101 | } 102 | } 103 | } 104 | } 105 | 106 | void list_attach(int data,List *pRear) { 107 | List P; 108 | 109 | P = (List) malloc(sizeof(struct Node)); 110 | P->Data = data; 111 | P->Next = NULL; 112 | 113 | (*pRear)->Next = P; //让尾节点的指针指向新的节点 114 | *pRear = P; //更新尾指针指向的位置 115 | } 116 | 117 | List create_list(int n) { 118 | 119 | List P, Rear, t; 120 | 121 | P = (List) malloc(sizeof(struct Node)); 122 | P->Next = NULL; 123 | Rear = P; 124 | 125 | for (int i = 0; i < n; i++) { 126 | list_attach(i, &Rear); 127 | } 128 | 129 | t = P; 130 | P = P->Next; 131 | free(t); 132 | 133 | return P; 134 | } 135 | 136 | void print_list(List P) { 137 | if (!P) { 138 | printf("null \n"); 139 | return; 140 | } 141 | 142 | while (P) { 143 | printf("%d\n", P->Data); 144 | P = P->Next; 145 | } 146 | 147 | printf("\n"); 148 | } 149 | 150 | //递归实现的反向输出链表中的偶数 151 | void r_print_even(List list) { 152 | if (list != NULL) { 153 | r_print_even(list->Next); 154 | 155 | if ((list->Data % 2) == 0) { 156 | cout << list->Data << endl; 157 | } 158 | } 159 | } 160 | 161 | 162 | //********************************************************************************* 163 | // 八皇后问题 164 | //********************************************************************************* 165 | static int g_chessboard[8] = { 0 }, gCount = 0; 166 | 167 | void print() //输出每一种情况下棋盘中皇后的摆放情况 168 | { 169 | for (int i = 0; i < 8; i++) { 170 | int inner; 171 | for (inner = 0; inner < g_chessboard[i]; inner++) 172 | cout << "0"; 173 | cout << "#"; 174 | for (inner = g_chessboard[i] + 1; inner < 8; inner++) 175 | cout << "0"; 176 | cout << endl; 177 | } 178 | cout << "==========================\n"; 179 | } 180 | 181 | int check_pos_valid(int loop, int value) //检查是否存在有多个皇后在同一行/列/对角线的情况 182 | { 183 | int index; 184 | int data; 185 | for (index = 0; index < loop; index++) { 186 | data = g_chessboard[index]; 187 | if (value == data) 188 | return 0; 189 | if ((index + data) == (loop + value)) 190 | return 0; 191 | if ((index - data) == (loop - value)) 192 | return 0; 193 | } 194 | return 1; 195 | } 196 | 197 | void eight_queen(int index) { 198 | int loop; 199 | for (loop = 0; loop < 8; loop++) { 200 | if (check_pos_valid(index, loop)) { 201 | g_chessboard[index] = loop; 202 | if (7 == index) { 203 | gCount++, print(); 204 | g_chessboard[index] = 0; 205 | return; 206 | } 207 | eight_queen(index + 1); 208 | g_chessboard[index] = 0; 209 | } 210 | } 211 | } 212 | 213 | int main(int argc, char*argv[]) { 214 | eight_queen(0); 215 | cout << "total=" << gCount << endl; 216 | return 0; 217 | } 218 | 219 | //int main() { 220 | // cout << "sum :" << sum(100) << endl; 221 | // 222 | // for(int i = 1;i <= 10;i++) 223 | // cout << "fac " << i << ":" << fac(i) << endl; 224 | // 225 | // cout << "str len:" << get_strlen("1234") << endl; 226 | // 227 | // HanoiTower(3, 'a', 'b', 'c'); 228 | 229 | // char string[] = "aaa"; 230 | // permutation(string,string); 231 | 232 | // List test = create_list(7); 233 | // print_list(test); 234 | // r_print_even(test); 235 | 236 | // return 0; 237 | //} 238 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/computer_system/indirection_operator.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static struct test_struct { 5 | int data1; 6 | int data2; 7 | }zzz1,zzz2; 8 | 9 | //间接引用操作符可以直接获得整个结构体大小的内存数据,这取决于所引用的指针变量的类型 10 | int indirection_operator() { 11 | setbuf(stdout,NULL); 12 | zzz1.data1 = 15; 13 | zzz1.data2 = 55; 14 | zzz2 = *((struct test_struct *)&zzz1); 15 | 16 | printf("zzz1.data1: %d, zzz1.data2 = %d\n",zzz1.data1,zzz1.data2); 17 | printf("zzz1.data1: %d, zzz1.data2 = %d\n",zzz1.data1,zzz1.data2); 18 | printf("zzz1.data1: %d, zzz1.data2 = %d\n",zzz1.data1,zzz1.data2); 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/computer_system/integer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int div16(int x) 5 | { 6 | int biss = (x >> 31) & 0xf; //计算偏置 7 | printf("biss: %d\n", biss); 8 | return (x + biss) >> 4; 9 | } 10 | 11 | int main() 12 | { 13 | setbuf(stdout,NULL); 14 | int test_number = -31; 15 | int result = 0; 16 | 17 | result = div16(test_number); 18 | 19 | 20 | printf("result: %d\n", result); 21 | 22 | printf("result: %d\n", test_number >> 4); 23 | return 0; 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /eclipse/DataStructuresCode/src/main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SummerGift/DataStructure/1103b05bc34be926fa734f05415bd52cfa5f733c/eclipse/DataStructuresCode/src/main.cpp -------------------------------------------------------------------------------- /eclipse/SummerGift_Lib/.cproject: -------------------------------------------------------------------------------- 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 | 29 | 30 | 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 | 75 | 76 | 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 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /eclipse/SummerGift_Lib/.gitignore: -------------------------------------------------------------------------------- 1 | /Debug/ 2 | -------------------------------------------------------------------------------- /eclipse/SummerGift_Lib/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | SummerGift_Lib 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | 14 | 15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 16 | full,incremental, 17 | 18 | 19 | 20 | 21 | 22 | org.eclipse.cdt.core.cnature 23 | org.eclipse.cdt.core.ccnature 24 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 25 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 26 | 27 | 28 | -------------------------------------------------------------------------------- /eclipse/SummerGift_Lib/.settings/language.settings.xml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /eclipse/SummerGift_Lib/.settings/org.eclipse.cdt.managedbuilder.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.975094256/CPATH/delimiter=; 3 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.975094256/CPATH/operation=remove 4 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.975094256/CPLUS_INCLUDE_PATH/delimiter=; 5 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.975094256/CPLUS_INCLUDE_PATH/operation=remove 6 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.975094256/C_INCLUDE_PATH/delimiter=; 7 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.975094256/C_INCLUDE_PATH/operation=remove 8 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.975094256/append=true 9 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.975094256/appendContributed=true 10 | environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.975094256/LIBRARY_PATH/delimiter=; 11 | environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.975094256/LIBRARY_PATH/operation=remove 12 | environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.975094256/append=true 13 | environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.975094256/appendContributed=true 14 | -------------------------------------------------------------------------------- /eclipse/SummerGift_Lib/.tracecompass/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | .tracecompass-SummerGift_Cpp_Lib 4 | 5 | 6 | 7 | 8 | 9 | 10 | org.eclipse.linuxtools.tmf.project.nature 11 | 12 | 13 | -------------------------------------------------------------------------------- /eclipse/SummerGift_Lib/src/SmartPointer.h: -------------------------------------------------------------------------------- 1 | #ifndef SMARTPOINTER_H_ 2 | #define SMARTPOINTER_H_ 3 | 4 | #include 5 | 6 | namespace SGLib { 7 | 8 | template 9 | class SmartPointer { 10 | 11 | protected: 12 | T* m_pointer; 13 | 14 | public: 15 | SmartPointer(T* p = NULL) { 16 | m_pointer = p; 17 | } 18 | 19 | SmartPointer(const SmartPointer& obj) { 20 | m_pointer = obj.m_pointer; 21 | const_cast&>(obj).m_pointer = NULL; 22 | } 23 | 24 | SmartPointer& operator=(const SmartPointer& obj) { 25 | if (this != &obj) { 26 | 27 | delete m_pointer; 28 | m_pointer = obj.m_pointer; 29 | const_cast&>(obj).m_pointer = NULL; 30 | } 31 | 32 | return *this; 33 | } 34 | 35 | T* operator->() { 36 | return m_pointer; 37 | } 38 | 39 | T& operator*() { 40 | return *m_pointer; 41 | } 42 | 43 | bool isNull() { 44 | return (m_pointer == NULL); 45 | } 46 | 47 | T* get() { 48 | return m_pointer; 49 | } 50 | 51 | ~SmartPointer() { 52 | delete m_pointer; 53 | } 54 | 55 | }; 56 | 57 | } 58 | 59 | #endif /* SMARTPOINTER_H_ */ 60 | -------------------------------------------------------------------------------- /eclipse/SummerGift_Lib/src/SummerGift_Lib.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "SmartPointer.h" 3 | 4 | using namespace std; 5 | using namespace SGLib; 6 | 7 | class hellosummer { 8 | public: 9 | hellosummer() { 10 | cout << "hello sumer" << endl; 11 | } 12 | 13 | ~hellosummer() { 14 | cout << "goodbbye sumer" << endl; 15 | } 16 | }; 17 | 18 | int main() { 19 | 20 | SmartPointer sp = new hellosummer(); 21 | SmartPointer s; 22 | 23 | s = sp; 24 | 25 | cout << "sp= " << sp.isNull() << endl; 26 | cout << "s= " << s.isNull() << endl; 27 | 28 | //s++; 29 | 30 | cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!! 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /sample_code/27_二阶构造模式代码/27-1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Test 4 | { 5 | int mi; 6 | int mj; 7 | bool mStatus; 8 | public: 9 | Test(int i, int j) : mStatus(false) 10 | { 11 | mi = i; 12 | 13 | return; 14 | 15 | mj = j; 16 | 17 | mStatus = true; 18 | } 19 | int getI() 20 | { 21 | return mi; 22 | } 23 | int getJ() 24 | { 25 | return mj; 26 | } 27 | int status() 28 | { 29 | return mStatus; 30 | } 31 | }; 32 | 33 | int main() 34 | { 35 | Test t1(1, 2); 36 | 37 | if( t1.status() ) 38 | { 39 | printf("t1.mi = %d\n", t1.getI()); 40 | printf("t1.mj = %d\n", t1.getJ()); 41 | 42 | } 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /sample_code/27_二阶构造模式代码/27-2.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SummerGift/DataStructure/1103b05bc34be926fa734f05415bd52cfa5f733c/sample_code/27_二阶构造模式代码/27-2.cpp -------------------------------------------------------------------------------- /sample_code/27_二阶构造模式代码/IntArray.cpp: -------------------------------------------------------------------------------- 1 | #include "IntArray.h" 2 | 3 | IntArray::IntArray(int len) 4 | { 5 | m_length = len; 6 | } 7 | 8 | bool IntArray::construct() 9 | { 10 | bool ret = true; 11 | 12 | m_pointer = new int[m_length]; 13 | 14 | if( m_pointer ) 15 | { 16 | for(int i=0; iconstruct()) ) 34 | { 35 | delete ret; 36 | ret = 0; 37 | } 38 | 39 | return ret; 40 | } 41 | 42 | int IntArray::length() 43 | { 44 | return m_length; 45 | } 46 | 47 | bool IntArray::get(int index, int& value) 48 | { 49 | bool ret = (0 <= index) && (index < length()); 50 | 51 | if( ret ) 52 | { 53 | value = m_pointer[index]; 54 | } 55 | 56 | return ret; 57 | } 58 | 59 | bool IntArray::set(int index, int value) 60 | { 61 | bool ret = (0 <= index) && (index < length()); 62 | 63 | if( ret ) 64 | { 65 | m_pointer[index] = value; 66 | } 67 | 68 | return ret; 69 | } 70 | 71 | IntArray::~IntArray() 72 | { 73 | delete[]m_pointer; 74 | } 75 | -------------------------------------------------------------------------------- /sample_code/27_二阶构造模式代码/IntArray.h: -------------------------------------------------------------------------------- 1 | #ifndef _INTARRAY_H_ 2 | #define _INTARRAY_H_ 3 | 4 | class IntArray 5 | { 6 | private: 7 | int m_length; 8 | int* m_pointer; 9 | 10 | IntArray(int len); 11 | IntArray(const IntArray& obj); 12 | bool construct(); 13 | public: 14 | static IntArray* NewInstance(int length); 15 | int length(); 16 | bool get(int index, int& value); 17 | bool set(int index ,int value); 18 | ~IntArray(); 19 | }; 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /sample_code/27_二阶构造模式代码/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "IntArray.h" 3 | 4 | int main() 5 | { 6 | IntArray* a = IntArray::NewInstance(5); 7 | 8 | printf("a.length = %d\n", a->length()); 9 | 10 | a->set(0, 1); 11 | 12 | for(int i=0; ilength(); i++) 13 | { 14 | int v = 0; 15 | 16 | a->get(i, v); 17 | 18 | printf("a[%d] = %d\n", i, v); 19 | } 20 | 21 | delete a; 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /sample_code/32_string_class/.cproject: -------------------------------------------------------------------------------- 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 | 29 | 30 | 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 | 75 | 76 | 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 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /sample_code/32_string_class/.gitignore: -------------------------------------------------------------------------------- 1 | /Debug/ 2 | -------------------------------------------------------------------------------- /sample_code/32_string_class/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | String_Class 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | 14 | 15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 16 | full,incremental, 17 | 18 | 19 | 20 | 21 | 22 | org.eclipse.cdt.core.cnature 23 | org.eclipse.cdt.core.ccnature 24 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 25 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 26 | 27 | 28 | -------------------------------------------------------------------------------- /sample_code/32_string_class/.settings/language.settings.xml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /sample_code/32_string_class/.settings/org.eclipse.cdt.managedbuilder.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.163128457/CPATH/delimiter=; 3 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.163128457/CPATH/operation=remove 4 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.163128457/CPLUS_INCLUDE_PATH/delimiter=; 5 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.163128457/CPLUS_INCLUDE_PATH/operation=remove 6 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.163128457/C_INCLUDE_PATH/delimiter=; 7 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.163128457/C_INCLUDE_PATH/operation=remove 8 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.163128457/append=true 9 | environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.163128457/appendContributed=true 10 | environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.163128457/LIBRARY_PATH/delimiter=; 11 | environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.163128457/LIBRARY_PATH/operation=remove 12 | environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.163128457/append=true 13 | environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.163128457/appendContributed=true 14 | -------------------------------------------------------------------------------- /sample_code/32_string_class/src/String_Class.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int main() 7 | { 8 | string s = "a1b2c3d4e345345"; 9 | int n = 0; 10 | 11 | for(int i = 0; i 2 | #include 3 | 4 | using namespace std; 5 | 6 | //#define SWAP(t, a, b) \ 7 | //do \ 8 | //{ \ 9 | // t c = a; \ 10 | // a = b; \ 11 | // b = c; \ 12 | //}while(0) 13 | // 14 | //void Swap(int& a, int& b) 15 | //{ 16 | // int c = a; 17 | // a = b; 18 | // b = c; 19 | //} 20 | 21 | template 22 | void Swap(T& a, T& b) { 23 | T c = a; 24 | a = b; 25 | b = c; 26 | } 27 | 28 | template 29 | void Sort(T a[], int len) { 30 | for (int i = 0; i < len; i++) { 31 | for (int j = i; j < len; j++) { 32 | // cout << "a[i] = " << a[i] << " a[j] = " << a[j] << endl; 33 | if (a[i] > a[j]) { 34 | Swap(a[i], a[j]); 35 | } 36 | } 37 | } 38 | } 39 | 40 | template 41 | void Println(T a[], int len) { 42 | for (int i = 0; i < len; i++) { 43 | cout << a[i] << ", "; 44 | } 45 | 46 | cout << endl; 47 | } 48 | 49 | //int main() { 50 | // int a[5] = { 5, 4, 3, 2, 1 }; 51 | // Println(a, 5); 52 | // Sort(a, 5); 53 | // Println(a, 5); 54 | // 55 | // string s[5] = { "java", "c++", "pascal", "ruby", "basic" }; 56 | // Println(s, 5); 57 | // Sort(s, 5); 58 | // Println(s, 5); 59 | // 60 | // float ab[5] = { 5.2, 4.123, 3.123, 2.455, 1.535 }; 61 | // Println(ab, 5); 62 | // Sort(ab, 5); 63 | // Println(ab, 5); 64 | // 65 | // return 0; 66 | //} 67 | 68 | -------------------------------------------------------------------------------- /sample_code/list/list.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SummerGift/DataStructure/1103b05bc34be926fa734f05415bd52cfa5f733c/sample_code/list/list.cpp -------------------------------------------------------------------------------- /sample_code/list/list.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SummerGift/DataStructure/1103b05bc34be926fa734f05415bd52cfa5f733c/sample_code/list/list.h --------------------------------------------------------------------------------