diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 00000000..6b778b10 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,21 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE" + ], + "windowsSdkVersion": "10.0.19041.0", + "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.28.29910/bin/Hostx64/x64/cl.exe", + "cStandard": "c17", + "cppStandard": "c++17", + "intelliSenseMode": "windows-msvc-x64" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/C++/test.cpp b/C++/test.cpp new file mode 100644 index 00000000..ab3b4290 --- /dev/null +++ b/C++/test.cpp @@ -0,0 +1,161 @@ +//二叉树的链表实现 +#include +#include +#include +using namespace std; + +struct TreeNode{ + int val; + TreeNode* left;//左子树 + TreeNode* right;//右子树 + TreeNode* parent;//可以不用 +}; +class BinaryTree{ + //TreeNode* root;//二叉树的根节点 + //vector tree;//二叉树的数组表示-1表示不存在的值 +public: + // 创建二叉树 + void build(TreeNode* &node,vector &vec,int i){ + if(i>vec.size() || vec[i]<0){ + return ; + } + node =new TreeNode(); + node->val = vec[i]; + build(node->left,vec,2*i+1); + build(node->right,vec,2*i+2); + return; + + } + //可视化二叉树 + void display(TreeNode*node){ + queue que; + que.push(node); + int i=1; + int j=0; + TreeNode* temp; + while(!que.empty()){ + + + if(que.front()==nullptr){ + que.pop(); + cout<<"\t"; + continue; + } + temp=que.front(); + que.pop(); + cout<val<<"\t"; + que.push(temp->left); + que.push(temp->right); + j++; + if(j==i){ + j=0; + i=2*i; + cout<val<<" "; + } + + + + //前序遍历 + void pre_order(TreeNode*node){ + if(node == nullptr){ + return; + } + process(node); + pre_order(node->left); + pre_order(node->right); + return; + } + //中序遍历 + void mid_order(TreeNode*node){ + if(node == nullptr){ + return; + } + mid_order(node->left); + process(node); + mid_order(node->right); + return; + } + //后续遍历 + void lst_order(TreeNode* node){ + if(node == nullptr){ + return; + } + lst_order(node->left); + lst_order(node->right); + process(node); + } + // 层序遍历 + void layer_order(TreeNode*node){ + queue que; + que.push(node); + while(!que.empty()){ + if(que.front()==nullptr){ + continue; + } + process(que.front()); + que.push(que.front()->left); + que.push(que.front()->right); + que.pop(); + } + } + //重建二叉树-前中 + /* + * pre 前序遍历的数组 + * mid 中序遍历的数组 + * root 前序遍历中的第一个数的坐标。也就是说,该子树的根节点。 + * beg2 中序遍历的起始位置。 + * end2 中序遍历的结束位置。 + * 问题分析:二叉树遍历问题,递归与分治的思想。创建一个树,可以分解为创建左子树和右子树两个子问题。问题的规模缩小。具有最优子结构性质,每一个子问题解法一致。子问题最终可以合并为问题的解。各个子问题相互独立。 + * 选择策略:使用链表数据结构存储结果。采用递归思想递归创建。 + * 算法技术:递归技术。算法流程,设计输入参数,界定本层处理范围。设计返回值即提供给上层的值。确定递归结构,分别调用左子树和右子树。确定递归的终止条件。确定递归前和递归后需要处理的内容。 + * 正确性证明。 + */ + TreeNode* rebuild(vector pre,vector mid,int root,int beg2,int end2){ + if(end2val=pre[root]; + for(i=beg2;i<=end2;i++){ + if(mid[i]==pre[root]){ + break; + } + } + int dis = i-beg2;//左树的长度 + node->left=rebuild(pre,mid,root+1,beg2,beg2+dis-1); + node->right=rebuild(pre,mid,root+dis+1,beg2+dis+1,end2); + return node; + } + TreeNode* rebuild2(); + + //重建二叉树-中后 +}; +int main(){ + //数组表示的树 + vector vec{9,8,7,6,-1,4,3}; + TreeNode n; + TreeNode* node=&n; + BinaryTree tree; + // tree.build(node,vec,0); + // tree.display(node); + // cout< pre{3,9,20,15,7}; + vector mid{9,3,15,20,7}; + TreeNode* node2 = tree.rebuild(pre,mid,0,0,mid.size()-1); + tree.display(node2); + return 0; +} \ No newline at end of file diff --git a/C++/标准库/6 正则表达式.md b/C++/标准库/6 正则表达式.md index 76eab574..166a3dfc 100644 --- a/C++/标准库/6 正则表达式.md +++ b/C++/标准库/6 正则表达式.md @@ -1,9 +1,14 @@ # 正则表达式 +> 目录 +> * regex正则表达式的定义 +> * regex_match/search/replace正则表达式的三个操作 +> * smatch、sregex_iterator正则表达式的结果对象以及与其配套的迭代器。 -## 1 正则表达式组件 - -## 1.1 正则表达式的基础用法 +> 参考文献 +> * [正则表达式总结](https://blog.csdn.net/haohao1945/article/details/51375609) +## 1 正则表达式基础 +> 不考虑子表达式的内容 ### 头文件 @@ -12,23 +17,145 @@ ``` ### 库组件 -![](image/2021-03-07-19-53-20.png) + +库组件 | 作用 +|----|----| +regex | 正则表达式类 +regex_match| 字符串与正则表达式进行匹配 +regex_search | 搜索第一个与正则表达式匹配的子序列 +regex_replace | 给定格式替换一个正则表达式 +smatch | 保存string中搜索的结果(s指string) +sregex_iterator|迭代器,遍历string搜索的结果(s指string) + + + +### 正则表达式regex + +```C++ +//定义正则表达式的对象。可以使用一个string、一个字符范围迭代器对、一个字符数组指针、一个字符和一个计数器、或括号括起来的字符列表。一个可选的flag参数,主要用来指定匹配规则 +string str = "hhh233"; +string pattern="[a-z0-9]+"; +regex r(pattern,[flag]); + +//重新制定r的正则表达式 +r.assign(pattern2,[flag]) + +//r中子表达式的数目 +r.mark_count(); + +//r中的标志位 +r.flags(); +``` + + - -### 正则表达式对象 - -![](image/2021-03-07-20-52-19.png) +## 2 操作 -### 操作 +## 2.1 正则匹配regex_match +函数|说明 +|----|----| +regex_match(string seq,regex r)|查询是否匹配。完全匹配。seq也可以是字符串迭代器对string.begin(),string.end() +regex_match(string seq,smatch m,regex r)|查询是否匹配,完全匹配。并返回匹配的结果。seq也可以是字符串迭代器对string.begin(),string.end() -![](image/2021-03-07-19-55-20.png) +* 头文件中的regex_match和regex_search均可以进行匹配,返回一个布尔类型,匹配成功为true,匹配失败为false。前者要求完全匹配,后者要求子串匹配即可; +* 对字符串进行匹配(一般不使用,因为字符串匹配的正则表达式要考虑到整个字符串) + +```C++ +string str = "hhh233"; +regex r("[a-z0-9]+"); + +// 用法一 +bool flag = regex_match(str,r); +// 用法二 +bool flag = regex_match(str,regex("\\d+")); +// 用法三 +bool flag = regex_match(str.begin()+7,str.end(),regex("\\d+")); + +//正则匹配 +string regex_str2("(\\d{4}).*"); +regex pattern2(regex_str2,regex::icase); + +if(regex_match(str,result,pattern2)){ + cout<match_result +``` +函数|说明 +|---|---| +m.ready()|是否接受过返回结果 +m.empty()|是否没哟匹配数。 +m.size()|查看捕捉到的分组的个数。smatch 类的 size() 指的是分组个数,也就是正则中左括号的个数。 +m.prefix().str() | 获取整个匹配之前的字符串; +m.suffix().str() | 获取整个匹配之后的字符串 +m.str(i),m[i].str(),*(m.begin() + i) | 获取第i个子匹配,即由正则分组匹配到的第i个匹配。 ```C++ #include @@ -48,21 +175,48 @@ int main(){ cout<> str; + regex e("([[:w:]]+)@([[:w:]]+)\.com"); + smatch m; + bool found = regex_search(str, m, e); + if(found) + { + cout << "m.size() " << m.size() << endl; + for(int i=0; i regex_iterator +``` + + +函数| 说明 +|----|----| +sregex_iterator it(string.beg(),string.end(),regex r)| 遍历迭代器begin和end之间的string。调用regex_search,返回并保存结果。 + + + +```C++ #include #include @@ -91,51 +245,58 @@ int main(){ return 0; } ``` -### smatch的操作,针对string -![](image/2021-03-07-21-07-30.png) - -## 1.3 子表达式的正则匹配 - -![](image/2021-03-07-21-10-18.png) -## 1.4 regex_replace - -![](image/2021-03-07-21-10-01.png) -## 2 正则表达式规则 +## 4 正则表达式规则 主要包括四类 * 字符类 * 数量限定符 * 位置限定符 * 特殊符号 - - -### 2.1 字符类 +### 4.0 正则表达式实例 +实例|说明 +|----|----| +| “ab"      | 表示以ab开头的字符串,例如”abc“ ”abc ed“ +| ”ab+"    | 表示一个字符串,由一个a和至少一个b组成 +| "ab?"    | 表示一个字符串,由一个a和一个或零个b组成 +| "ab{2,3}"  | 表示一个字符串,由一个a和2-3个b组成 +| “access|boot"  | 表示一个字符串,为access或者boot +| "(a|b)*c"   | 表示一个字符串,  由一个或多个a(或者b) + c 混合而成 +| [a-zA-Z]  | 表示一个字符,为一个字母 +| ”[a-zA-Z0-9]$"   | 表示一个字符串,由一个字母或数字结束。 +| **错误提示!!!!**[ab\\d]  | 中括号中不能有转义字符 +”[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,12})+ “          | 检验普通电话、传真号码:可以“+”或数字开头,可含有减号和空格 +”http[s]{0,1}:\/\/.+$/ 或 /^http[s]{0,1}:\/\/.{1,n}“    | 检验URL +“([0-9A-F]{2})(-[0-9A-F]{2}){5}”                          | 检验mac地址 +“[-+]?\d+(\.\d+)?”                                        |       值类型 +“\\d{4}-\\d{1,2}-\\d{1,2}”                                |      日期格式2018-7-30 +”(\\d+){5,11}@(\\w+)\\.(\\w){3}“                        | QQ邮箱格式  +### 4.1 字符类 ![](image/2021-03-07-20-17-59.png) -### 2.2 数量限定符 +### 4.2 数量限定符 ![](image/2021-03-07-20-18-20.png) -### 2.3 位置限定符 +### 4.3 位置限定符 ![](image/2021-03-07-20-18-37.png) -### 2.4 特殊符号 +### 4.4 特殊符号 ![](image/2021-03-07-20-18-51.png) -### 2.5 普通字符集及其替换 +### 4.5 普通字符集及其替换 ![](image/2021-03-07-20-20-11.png) -### 2.6 贪婪模式与非贪婪模式 +### 4.6 贪婪模式与非贪婪模式 1. 贪婪模式:正则表达式匹配时,会尽量多的匹配符合条件的内容。 2. 非贪婪模式:正则表达式匹配时,会尽量少的匹配符合条件的内容,也就是说,一旦发现匹配符合要求,立马就匹配成功,而不会继续匹配下去(除非有g,开启下一组匹配) -### 2.7 特殊规则 +### 4.7 特殊规则 * '[:alnum:]' 匹配任何字母和数字 Alphanumeric characters: '[:alpha:]' and '[:digit:]'. @@ -174,7 +335,7 @@ X Y Z'. * '[:xdigit:]' 匹配任何16进制数字 Hexadecimal digits: '0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f'. -### 2.8 正则规则速查表 +### 4.8 正则规则速查表 | **字符** | **描述** | |--------------|----------------| diff --git a/C++/标准库/6.cpp b/C++/标准库/6.cpp index dfaf4ab8..657f4812 100644 --- a/C++/标准库/6.cpp +++ b/C++/标准库/6.cpp @@ -23,5 +23,149 @@ int main(){ for(;it != end_it;++it){ cout<str()< result; + //第二种存储方式 + smatch result; + + //文本数据 + string str="1994 is my birth year 1994"; + //正则表达式 + string regex_str("\\d{4}"); + regex pattern1(regex_str,regex::icase); + + //迭代器声明 + string::const_iterator iter = str.begin(); + string::const_iterator iterEnd= str.end(); + string temp; + //正则查找 + while (std::regex_search(iter,iterEnd,result,pattern1)) + { + temp=result[0]; + cout< str{ "010-12345678", "0319-9876543", "021-123456789"}; + + /* std::regex_match: + 判断一个正则表达式(参数re)是否匹配整个字符序列str,它主要用于验证文本 + 注意,这个正则表达式必须匹配被分析串的全部,否则返回false;如果整个序列被成功匹配,返回true + */ + + for (auto tmp : str) { + bool ret = std::regex_match(tmp, re); + if (ret) fprintf(stderr, "%s, can match\n", tmp.c_str()); + else fprintf(stderr, "%s, can not match\n", tmp.c_str()); + } + + return 0; +} + +int test_regex_search() +{ + std::string pattern{ "http|hppts://\\w*$" }; // url + std::regex re(pattern); + + std::vector str{ "http://blog.csdn.net/fengbingchun", "https://github.com/fengbingchun", + "abcd://124.456", "abcd https://github.com/fengbingchun 123" }; + + /* std::regex_search: + 类似于regex_match,但它不要求整个字符序列完全匹配 + 可以用regex_search来查找输入中的一个子序列,该子序列匹配正则表达式re + */ + + for (auto tmp : str) { + bool ret = std::regex_search(tmp, re); + if (ret) fprintf(stderr, "%s, can search\n", tmp.c_str()); + else fprintf(stderr, "%s, can not search\n", tmp.c_str()); + } + + return 0; +} + +int test_regex_search2() +{ + std::string pattern{ "[a-zA-z]+://[^\\s]*" }; // url + std::regex re(pattern); + + std::string str{ "my csdn blog addr is: http://blog.csdn.net/fengbingchun , my github addr is: https://github.com/fengbingchun " }; + std::smatch results; + while (std::regex_search(str, results, re)) { + for (auto x : results) + std::cout << x << " "; + std::cout << std::endl; + str = results.suffix().str(); + } + + return 0; +} + +int test_regex_replace() +{ + std::string pattern{ "\\d{18}|\\d{17}X" }; // id card + std::regex re(pattern); + + std::vector str{ "123456789012345678", "abcd123456789012345678efgh", + "abcdefbg", "12345678901234567X" }; + std::string fmt{ "********" }; + + /* std::regex_replace: + 在整个字符序列中查找正则表达式re的所有匹配 + 这个算法每次成功匹配后,就根据参数fmt对匹配字符串进行替换 + */ + + for (auto tmp : str) { + std::string ret = std::regex_replace(tmp, re, fmt); + fprintf(stderr, "src: %s, dst: %s\n", tmp.c_str(), ret.c_str()); + } + + return 0; +} + +int test_regex_replace2() +{ + // reference: http://www.cplusplus.com/reference/regex/regex_replace/ + std::string s("there is a subsequence in the string\n"); + std::regex e("\\b(sub)([^ ]*)"); // matches words beginning by "sub" + + // using string/c-string (3) version: + std::cout << std::regex_replace(s, e, "sub-$2"); + + // using range/c-string (6) version: + std::string result; + std::regex_replace(std::back_inserter(result), s.begin(), s.end(), e, "$2"); + std::cout << result; + + // with flags: + std::cout << std::regex_replace(s, e, "$1 and $2", std::regex_constants::format_no_copy); + std::cout << std::endl; + return 0; } \ No newline at end of file diff --git a/数据结构/1.cpp b/数据结构/1.cpp index cb5641c9..a808f1ad 100644 --- a/数据结构/1.cpp +++ b/数据结构/1.cpp @@ -1,3 +1,4 @@ +//数组的创建、遍历、插入、删除 #include using namespace std; diff --git a/数据结构/2.1.cpp b/数据结构/2.1.cpp index 57f4df4c..ee338f2f 100644 --- a/数据结构/2.1.cpp +++ b/数据结构/2.1.cpp @@ -1,3 +1,4 @@ +// 单链表的创建、遍历、插入、删除 #include #include struct node diff --git a/数据结构/2.2.cpp b/数据结构/2.2.cpp index 3ca45fd0..92edc863 100644 --- a/数据结构/2.2.cpp +++ b/数据结构/2.2.cpp @@ -1,3 +1,4 @@ +// 双链表的创建、遍历、插入、删除 #include #include struct node diff --git a/数据结构/2.3.cpp b/数据结构/2.3.cpp index 205350f3..dc5ceb57 100644 --- a/数据结构/2.3.cpp +++ b/数据结构/2.3.cpp @@ -1,3 +1,4 @@ +// 循环链表的创建、遍历、插入和删除 #include #include struct node diff --git a/数据结构/2.4.cpp b/数据结构/2.4.cpp index 19b6d129..dd031016 100644 --- a/数据结构/2.4.cpp +++ b/数据结构/2.4.cpp @@ -1,3 +1,4 @@ +//循环双链表的创建、遍历、插入和删除 #include #include struct node diff --git a/数据结构/3.cpp b/数据结构/3.cpp new file mode 100644 index 00000000..5f18fd9d --- /dev/null +++ b/数据结构/3.cpp @@ -0,0 +1 @@ +// 栈的创建、遍历、插入和删除 \ No newline at end of file diff --git a/数据结构/4.cpp b/数据结构/4.cpp new file mode 100644 index 00000000..55ca02d2 --- /dev/null +++ b/数据结构/4.cpp @@ -0,0 +1 @@ +// 队列的创建、遍历、插入和删除 \ No newline at end of file diff --git a/数据结构/6.1 二叉树.md b/数据结构/6.1 二叉树.md index 4352e34a..a5303792 100644 --- a/数据结构/6.1 二叉树.md +++ b/数据结构/6.1 二叉树.md @@ -56,16 +56,61 @@ ### 前序遍历 -``` +* 第一个节点肯定是根节点。 +```C++ + //前序遍历 + void pre_order(TreeNode*node){ + if(node == nullptr){ + return; + } + process(node); + pre_order(node->left); + pre_order(node->right); + return; + } ``` ### 中序遍历 -``` +```C++ + //中序遍历 + void mid_order(TreeNode*node){ + if(node == nullptr){ + return; + } + mid_order(node->left); + process(node); + mid_order(node->right); + return; + } ``` ### 后序遍历 -``` +* 最后一个节点肯定是根节点。 +```C++ + //后续遍历 + void lst_order(TreeNode* node){ + if(node == nullptr){ + return; + } + lst_order(node->left); + lst_order(node->right); + process(node); + } ``` ### 层序遍历 -``` +```C++ + // 层序遍历 + void layer_order(TreeNode*node){ + queue que; + que.push(node); + while(!que.empty()){ + if(que.front()==nullptr){ + continue; + } + process(que.front()); + que.push(que.front()->left); + que.push(que.front()->right); + que.pop(); + } + } ``` ## 4 二叉树实现 @@ -85,6 +130,12 @@ ``` ``` +## 重建二叉树问题 + +* 给定了二叉树的任何一种遍历序列,都无法唯一确定相应的二叉树。 +* 如果知道了二叉树的中序遍历序列和任意的另一种遍历序列,就可以唯一地确定二叉树。 + +* 中序遍历能够分出子树的根节点的左右。中序和后序遍历能够区根节点。 ## 5 二叉树相关的问题 diff --git a/数据结构/6.1.cpp b/数据结构/6.1.cpp new file mode 100644 index 00000000..9263b108 --- /dev/null +++ b/数据结构/6.1.cpp @@ -0,0 +1,192 @@ +//二叉树的链表实现 +#include +#include +#include +#include +using namespace std; + +struct TreeNode{ + int val; + TreeNode* left;//左子树 + TreeNode* right;//右子树 + TreeNode* parent;//可以不用 +}; +class BinaryTree{ + //TreeNode* root;//二叉树的根节点 + //vector tree;//二叉树的数组表示-1表示不存在的值 +public: + // 创建二叉树 + void build(TreeNode* &node,vector &vec,int i){ + if(i>vec.size() || vec[i]<0){ + return ; + } + node =new TreeNode(); + node->val = vec[i]; + build(node->left,vec,2*i+1); + build(node->right,vec,2*i+2); + return; + + } + //可视化二叉树 + void display(TreeNode*node){ + queue que; + que.push(node); + int i=1; + int j=0; + TreeNode* temp; + while(!que.empty()){ + + + if(que.front()==nullptr){ + que.pop(); + cout<<"\t"; + continue; + } + temp=que.front(); + que.pop(); + cout<val<<"\t"; + que.push(temp->left); + que.push(temp->right); + j++; + if(j==i){ + j=0; + i=2*i; + cout<val<<" "; + } + + + + //前序遍历 + void pre_order(TreeNode*node){ + if(node == nullptr){ + return; + } + process(node); + pre_order(node->left); + pre_order(node->right); + return; + } + //中序遍历 + void mid_order(TreeNode*node){ + if(node == nullptr){ + return; + } + mid_order(node->left); + process(node); + mid_order(node->right); + return; + } + //后续遍历 + void lst_order(TreeNode* node){ + if(node == nullptr){ + return; + } + lst_order(node->left); + lst_order(node->right); + process(node); + } + // 层序遍历 + void layer_order(TreeNode*node){ + queue que; + que.push(node); + while(!que.empty()){ + if(que.front()==nullptr){ + continue; + } + process(que.front()); + que.push(que.front()->left); + que.push(que.front()->right); + que.pop(); + } + } + // 区分层次的层序遍历 + vector> levelOrder(TreeNode* root) { + vector> vec; + queue que[2]; + que[0].push(root); + int i=0; + + while(!que[i%2].empty()){ + // 每次交换队列创建一个数组 + vec.push_back(vector()); + + while(!que[i%2].empty()){ + if(que[i%2].front()==nullptr){ + que[i%2].pop(); + continue; + } + TreeNode*temp=que[i%2].front(); + que[i%2].pop(); + vec[i].push_back(temp->val); + que[(i+1)%2].push(temp->left); + que[(i+1)%2].push(temp->right); + } + //可以在这里针对每层进行操作。例如反转。 + i++; + } + + // 最后肯定是空元素组成的队列,创建一个额外的空数组。 + vec.pop_back(); + return vec; + } + //重建二叉树-前中 + /* + * pre 前序遍历的数组 + * mid 中序遍历的数组 + * root 前序遍历中的第一个数的坐标。也就是说,该子树的根节点。 + * beg2 中序遍历的起始位置。 + * end2 中序遍历的结束位置。 + * 问题分析:二叉树遍历问题,递归与分治的思想。创建一个树,可以分解为创建左子树和右子树两个子问题。问题的规模缩小。具有最优子结构性质,每一个子问题解法一致。子问题最终可以合并为问题的解。各个子问题相互独立。 + * 选择策略:使用链表数据结构存储结果。采用递归思想递归创建。 + * 算法技术:递归技术。算法流程,设计输入参数,界定本层处理范围。设计返回值即提供给上层的值。确定递归结构,分别调用左子树和右子树。确定递归的终止条件。确定递归前和递归后需要处理的内容。 + * 正确性证明。 + */ + TreeNode* rebuild(vector pre,vector mid,int root,int beg2,int end2){ + if(end2val=pre[root]; + for(i=beg2;i<=end2;i++){ + if(mid[i]==pre[root]){ + break; + } + } + int dis = i-beg2;//左树的长度 + node->left=rebuild(pre,mid,root+1,beg2,beg2+dis-1); + node->right=rebuild(pre,mid,root+dis+1,beg2+dis+1,end2); + return node; + } + TreeNode* rebuild2(); + + //重建二叉树-中后 +}; +int main(){ + //数组表示的树 + vector vec{9,8,7,6,-1,4,3}; + TreeNode n; + TreeNode* node=&n; + BinaryTree tree; + // tree.build(node,vec,0); + // tree.display(node); + // cout< pre{3,9,20,15,7}; + vector mid{9,3,15,20,7}; + TreeNode* node2 = tree.rebuild(pre,mid,0,0,mid.size()-1); + tree.display(node2); + return 0; +} \ No newline at end of file diff --git a/数据结构/6.2 二叉搜索树.md b/数据结构/6.2 二叉搜索树.md index 98f51975..53945e1d 100644 --- a/数据结构/6.2 二叉搜索树.md +++ b/数据结构/6.2 二叉搜索树.md @@ -26,7 +26,10 @@ * 插入 * 删除 - +### 遍历 +* 二叉搜索树的前序遍历。 +* 二叉搜索书的中序遍历。中序的输出结果其实就是二叉搜索树排序后的结果。 +* 二叉搜索树的后续遍历。 ### 插入 * 使用下列元素创建二叉树的过程 ``` diff --git a/算法/A类:基本算法/4 递归与分治法.md b/算法/A类:基本算法/4 递归与分治法.md index 6f0b74e2..70ee509c 100644 --- a/算法/A类:基本算法/4 递归与分治法.md +++ b/算法/A类:基本算法/4 递归与分治法.md @@ -121,10 +121,12 @@ $$ ### 递归的实现 -* 设计递归的终止条件 -* 设计递归的返回值 -* 递归前的数据处理 -* 递归后的数据处理 +1. 设计递归的参数。首先确定每一次递归,上一层需要提供给下一层的内容。 +2. 设计递归的返回值。设计递归需要返回的内容,即提供给上一层的内容。 +3. 设计递归的开始。设计如何开始递归。怎样调用递归。有了上一层的参数和返回值的需求,相当于提供了一个函数的接口。那么就可以调用递归函数,开始递归了。 +4. 设计递归的终止条件。一旦开始递归,就要设计递归的终止条件。 +5. 递归前的数据处理。在递归前需要处理的数据,提供给递归函数。 +6. 递归后的数据处理。在递归后需要处理的数据。提供给上层函数和最终结果。 diff --git a/编译原理/1 简介.md b/编译原理/1 简介.md new file mode 100644 index 00000000..e69de29b