更新数据结构第五章
19
README.md
@@ -3,11 +3,14 @@
|
||||
## 写在前面:
|
||||
+ 408的四门科目的知识点总结,内容排版上结合CS408课本和王道计算机,并结合了作者完成王道课后题时所踩的坑的总结(在文件里特别标出)
|
||||
|
||||
+ **采用xmind制作,请使用最新xmind版本打开。**
|
||||
+ **采用XMind:ZEN 2020制作,请使用等于或高于此版本的XMind打开。**
|
||||
|
||||
+ 能填多少坑取决于作者决定考哪个学校;如果决定的学校不是考408,那我只会更新那个学校的科目的总结(┓( ´∀` )┏)咕咕咕
|
||||
|
||||
+ 如果对你有帮助有启发,欢迎**点个star**资瓷一下作者;同时欢迎有**对内容更好想法/懂得xmind排版**的朋友提交issue帮助这个项目更好
|
||||
+ 如果对你有帮助有启发,欢迎**点个star**资瓷一下作者;同时欢迎有**对内容更好想法/懂得xmind排版**的朋友提交issue帮助这个项目更好
|
||||
|
||||
## NOTE:
|
||||
+ 不适合在XMind里表达的内容,全部写在了同文件夹里的`*.md`文件或是`*.cpp`文件;一个文件夹里应该关注的仅有`*.xmind, *.md, *.cpp`文件,其余可以不用管
|
||||
|
||||
> 或许你也可以参考[这个项目](https://github.com/SSHeRun/CS-Xmind-Note)
|
||||
|
||||
@@ -26,8 +29,8 @@
|
||||
+ [x] [第一章 绪论](https://github.com/Alice-and-Bob/CS408/blob/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E7%AC%AC%E4%B8%80%E7%AB%A0%20%E7%BB%AA%E8%AE%BA/%E7%AC%AC%E4%B8%80%E7%AB%A0%20%E7%BB%AA%E8%AE%BA.xmind)
|
||||
+ [x] [第二章 线性表](https://github.com/Alice-and-Bob/CS408/blob/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E7%AC%AC%E4%BA%8C%E7%AB%A0%20%E7%BA%BF%E6%80%A7%E8%A1%A8/%E7%AC%AC%E4%BA%8C%E7%AB%A0%20%E7%BA%BF%E6%80%A7%E8%A1%A8.xmind)
|
||||
+ [x] [第三章 栈和队列](https://github.com/Alice-and-Bob/CS408/blob/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E7%AC%AC%E4%B8%89%E7%AB%A0%20%E6%A0%88%E5%92%8C%E9%98%9F%E5%88%97/%E7%AC%AC%E4%B8%89%E7%AB%A0%20%E6%A0%88%E4%B8%8E%E9%98%9F%E5%88%97.xmind)
|
||||
+ [x] 第四章 串
|
||||
+ [ ] 第五章 树与二叉树
|
||||
+ [x] [第四章 串](https://github.com/Alice-and-Bob/CS408/blob/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E7%AC%AC%E5%9B%9B%E7%AB%A0%20%E4%B8%B2/%E7%AC%AC%E5%9B%9B%E7%AB%A0%20%E4%B8%B2.xmind)
|
||||
+ [x] 第五章 树与二叉树
|
||||
+ [ ] 第六章 图
|
||||
+ [ ] 第七章 查找
|
||||
+ [ ] 第八章 排序
|
||||
@@ -36,8 +39,8 @@
|
||||
## 计算机组成原理
|
||||
|
||||
|
||||
## 网络安全基础与应用
|
||||
+ [x] 第一章 概论
|
||||
+ [x] 第二章 密码学
|
||||
+ [x] 第三章 应用安全
|
||||
## 网络安全基础与应用
|
||||
+ [x] [第一章 概论](https://github.com/Alice-and-Bob/CS408/blob/master/%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8%E5%9F%BA%E7%A1%80%E4%B8%8E%E5%BA%94%E7%94%A8/1%E3%80%81%E6%A6%82%E8%AE%BA.xmind)
|
||||
+ [x] [第二章 密码学](https://github.com/Alice-and-Bob/CS408/blob/master/%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8%E5%9F%BA%E7%A1%80%E4%B8%8E%E5%BA%94%E7%94%A8/2%E3%80%81%E5%AF%86%E7%A0%81%E5%AD%A6.xmind)
|
||||
+ [x] [第三章 应用安全](https://github.com/Alice-and-Bob/CS408/blob/master/%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8%E5%9F%BA%E7%A1%80%E4%B8%8E%E5%BA%94%E7%94%A8/3%E3%80%81%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8%E5%BA%94%E7%94%A8.xmind)
|
||||
+ [ ] 第四章 系统安全
|
||||
30
数据结构/第五章 树与二叉树/二叉排序树.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# 二叉排序树的非递归查找算法
|
||||
```cpp
|
||||
BSTNode *BST_Search(BinTree T, ElemType key){
|
||||
while(T!=NULL;&&key!=T->data){
|
||||
if(key < T->data)
|
||||
T = T->lchild;
|
||||
else
|
||||
T = T->rchild;
|
||||
}
|
||||
return T;
|
||||
}
|
||||
```
|
||||
|
||||
# 二叉排序树的插入算法
|
||||
```cpp
|
||||
int BST_Insert(BiTree &T, KeyType k){
|
||||
if(T==NULL){
|
||||
T=(BiTree)malloc(sizeof(BSTNode));
|
||||
T->key=k;
|
||||
T->lchild=T->rchild=NULL;
|
||||
return 1;
|
||||
}
|
||||
else if(k==T->key)
|
||||
return 0;
|
||||
else if(k < T->key)
|
||||
return BST_Insert(T->lchild);
|
||||
else
|
||||
return BST_Insert(T->rchild);
|
||||
}
|
||||
```
|
||||
134
数据结构/第五章 树与二叉树/二叉树的遍历.md
Normal file
@@ -0,0 +1,134 @@
|
||||
# 二叉树的遍历
|
||||
> 遍历的顺序是指根结点的访问次序,先序指首先访问根结点,再访问左子树,访问右子树;其他顺序遍历以此类推
|
||||
## 先序遍历
|
||||
> 若二叉树为空,什么也不做,否则:
|
||||
> 1、访问根结点
|
||||
> 2、先序遍历左子树
|
||||
> 3、先序遍历右子树
|
||||
```cpp
|
||||
void PreOrder(BinTree T){
|
||||
if(T!=NULL){
|
||||
visit(T);
|
||||
PreOrder(T->lchild);
|
||||
PreOrder(T->rchild);
|
||||
}
|
||||
}
|
||||
```
|
||||
## 中序遍历
|
||||
> 若二叉树为空,什么也不做,否则:
|
||||
> 1、中序遍历左子树
|
||||
> 2、访问根结点
|
||||
> 3、中序遍历右子树
|
||||
```cpp
|
||||
void InOrder(BinTree T){
|
||||
if(T!=NULL){
|
||||
InOrder(T->lchild);
|
||||
visit(T);
|
||||
InOrder(T->rchild);
|
||||
}
|
||||
}
|
||||
```
|
||||
## 后序遍历
|
||||
> 若二叉树为空,什么也不做,否则:
|
||||
> 1、后序遍历左子树
|
||||
> 2、后序遍历右子树
|
||||
> 3、访问根结点
|
||||
```cpp
|
||||
void PostOrder(BinTree T){
|
||||
if(T!=NULL){
|
||||
PostOrder(T->lchild);
|
||||
PostOrder(T->rchild);
|
||||
visit(T);
|
||||
}
|
||||
}
|
||||
```
|
||||
## 递归、非递归算法转换
|
||||
> 以上三种遍历算法采用递归,若采用非遍历算法,须使用栈
|
||||
### 中序遍历非递归算法
|
||||
> 分析遍历过程可以得出非递归算法:①从跟结点开始,一直访问结点的左孩子,并把结点入栈,当结点没有左孩子时,弹出栈顶结点访问;②若右孩子为空,则继续执行②,若不空,则对右子树执行①
|
||||
|
||||
```cpp
|
||||
void InOrder2(BinTree T){
|
||||
InitStack(S);
|
||||
BiTree p=T;
|
||||
while(p||!IsEmpty(S)){
|
||||
if(p){
|
||||
Push(S,p);
|
||||
p=p->lchild;
|
||||
}
|
||||
else{
|
||||
Pop(S,p);
|
||||
visit(p);
|
||||
p=p->rchild;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 先序遍历非递归算法
|
||||
|
||||
```cpp
|
||||
void PreOrder2(BinTree T){
|
||||
InitStack(S);
|
||||
BiTree p=T;
|
||||
while(p||!IsEmpty(S)){
|
||||
if(p){
|
||||
visit(p);
|
||||
Push(S,p);
|
||||
p=p->lchild;
|
||||
}
|
||||
else{
|
||||
Pop(S,p);
|
||||
p=p->rchild;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
### 后序遍历非递归算法
|
||||
> ①沿着根结点的左孩子,把结点依次入栈,直到左孩子为空;②读栈顶元素,当其右孩子非空且未被访问过时,则对右子树执行①,否则弹出栈顶元素并访问
|
||||
|
||||
```cpp
|
||||
void PostOrder(BiTree T){
|
||||
InitStack(S);
|
||||
p=T; //当前访问的结点
|
||||
r=NULL; //记录最近访问的结点
|
||||
while(p||!IsEmpty(S)){
|
||||
if(p){
|
||||
push(S,p);
|
||||
p=p->lchild;
|
||||
}
|
||||
else{
|
||||
GetTop(S,p);
|
||||
if(p->rchild && p->rchild!=r){ //右子树存在且最近未被访问过
|
||||
p=p->rchild;
|
||||
push(S,p);
|
||||
p=p->lchild;
|
||||
}
|
||||
else{
|
||||
pop(S,p);
|
||||
visit(p->data);
|
||||
r=p;
|
||||
p=NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 层次遍历
|
||||
> 层次遍历即是广度优先遍历,使用队列完成层次遍历
|
||||
```cpp
|
||||
void LevelOrder(BiTree T){
|
||||
InitQueue(Q);
|
||||
BiTree p;
|
||||
EnQueue(Q, T);
|
||||
while(!IsEmpty(Q)){
|
||||
DeQueue(Q,p);
|
||||
visit(p);
|
||||
if(p->lchild!=NULL)
|
||||
EnQueue(Q, p->lchild);
|
||||
else(p->rchild!=NULL)
|
||||
EnQueue(Q, p->rchild);
|
||||
}
|
||||
}
|
||||
```
|
||||
BIN
数据结构/第五章 树与二叉树/批注 2020-07-11 154229.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
数据结构/第五章 树与二叉树/批注 2020-07-11 171429.png
Normal file
|
After Width: | Height: | Size: 125 KiB |
BIN
数据结构/第五章 树与二叉树/批注 2020-07-14 170228.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
数据结构/第五章 树与二叉树/批注 2020-07-14 173314.png
Normal file
|
After Width: | Height: | Size: 149 KiB |
BIN
数据结构/第五章 树与二叉树/批注 2020-07-14 173332.png
Normal file
|
After Width: | Height: | Size: 176 KiB |
BIN
数据结构/第五章 树与二叉树/批注 2020-07-14 173346.png
Normal file
|
After Width: | Height: | Size: 192 KiB |
BIN
数据结构/第五章 树与二叉树/批注 2020-07-14 173401.png
Normal file
|
After Width: | Height: | Size: 214 KiB |
BIN
数据结构/第五章 树与二叉树/批注 2020-07-14 175139.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
数据结构/第五章 树与二叉树/第五章 树与二叉树.xmind
Normal file
63
数据结构/第五章 树与二叉树/线索二叉树.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# 线索二叉树
|
||||
## 数据结构
|
||||
```cpp
|
||||
typedef struct ThreadNode{
|
||||
ElemType data;
|
||||
struct ThreadNode *lchild, *rchild; //左右孩子指针
|
||||
int ltag,rtag; //左右线索标志
|
||||
}ThreadNode, *ThreadTree;
|
||||
```
|
||||
规定:当结点没有左孩子,其lchild指向其前驱节点;当没有右孩子,其rchild指向其后继结点
|
||||
## 二叉树中序线索化
|
||||
```cpp
|
||||
void InThread(ThreadTree &p, ThreadTree &pre){
|
||||
if(p!=NULL){
|
||||
InThread(p->lchild, pre);
|
||||
if(p->lchild==NULL){
|
||||
p->lchild=pre;
|
||||
p->ltag=1;
|
||||
}
|
||||
if(pre!=NULL&&pre->rchild==NULL){
|
||||
pre->rchild=p;
|
||||
pre->rtag=1;
|
||||
}
|
||||
pre=p;
|
||||
InThread(p->rchild, pre);
|
||||
}
|
||||
}
|
||||
|
||||
void CreateInThread(ThreadTree T){
|
||||
ThreadTree pre=NULL;
|
||||
if(T!=NULL){ //非空二叉树
|
||||
InThread(T, pre); //线索化二叉树
|
||||
pre->rchild=NULL; //处理遍历的最后一个结点
|
||||
pre->rtag=1;
|
||||
}
|
||||
}
|
||||
```
|
||||
## 中序线索二叉树的遍历
|
||||
1. 中序线索二叉树下的第一个结点
|
||||
```cpp
|
||||
ThreadNode *Firstnode(ThreadNode *p){
|
||||
while(p->ltag==0)
|
||||
p=p->lchild;
|
||||
return p;
|
||||
}
|
||||
```
|
||||
2. 中序线索二叉树下某结点p的后继
|
||||
```cpp
|
||||
ThreadNode *Nextnode(ThreadNode *p){
|
||||
if(p->rtag==0) //右孩子存在
|
||||
return Firstnode(p->rchild)
|
||||
else
|
||||
return p->rchild;
|
||||
}
|
||||
```
|
||||
3. 不带头结点的中序线索二叉树的中序遍历的算法
|
||||
```cpp
|
||||
void Inorder(ThreadNode *T){
|
||||
for(ThreadNode *p=Firstnode(T); p!=NULL; p=Nextnode(p)){
|
||||
visit(p);
|
||||
}
|
||||
}
|
||||
```
|
||||