值为x的结点不多于1个,也就是最多只有一个
typedef struct{
BiTree t;
int tag;
}stack;
void Search(BiTree T,ElemType x){
stack s[];
top=0;
while(T!=NULL||top>0){
while(T!=NULL&&T->data!=x){
s[++top].t=T;
s[top].tag=0;
T=T->lchild;
}
if(T!=NULL&&T->data==x){
printf("所查结点的所有祖先节点值为:\n");
for(i=1;i<=top;i++)
printf("%d ",s[i].t->data);
exit(1);
}
while(top!=0&&s[top].tag==1)
top--;
if(top!=0){
s[top].tag=1;
T=s[top].t->rchild;
}
}
}
### 定义栈结构
```cpp
typedef struct{
BiTree t;
int tag;
}stack;
```
- **定义结构体**:定义了一个结构体 `stack`,其中包含了一个指向二叉树节点的指针 `t` 和一个整型 `tag`。`tag` 用于标记树节点是否被访问过。
### 函数 `Search`
```cpp
void Search(BiTree T, ElemType x){
```
- **函数定义**:这个函数用于在二叉树中查找并输出指定值 `x` 的节点的所有祖先节点。
```cpp
stack s[];
top=0;
```
- **定义栈和栈顶指针**:定义了一个栈 `s`,并初始化栈顶指针 `top` 为0。
```cpp
while(T!=NULL||top>0){
```
- **循环条件**:当二叉树不为空或者栈不为空时,进行循环。
```cpp
while(T!=NULL&&T->data!=x){
```
- **内循环条件**:当当前节点不为空且其值不等于目标值 `x` 时,执行内循环。
```cpp
s[++top].t=T;
s[top].tag=0;
T=T->lchild;
```
- **栈操作**:将当前节点压入栈中,并将 `tag` 标记为0,表示该节点未被访问。然后将当前节点移动到其左子节点。
```cpp
}
if(T!=NULL&&T->data==x){
printf("所查结点的所有祖先节点值为:\n");
for(i=1;i<=top;i++)
printf("%d ",s[i].t->data);
exit(1);
}
```
- **节点值匹配检查**:如果当前节点的值等于目标值 `x`,则输出该节点的所有祖先节点值,并退出程序。
```cpp
while(top!=0&&s[top].tag==1)
top--;
```
- **出栈操作**:当栈不为空且栈顶节点已经被访问过时,执行出栈操作。
```cpp
if(top!=0){
s[top].tag=1;
T=s[top].t->rchild;
}
```
- **栈顶元素标记**:如果栈不为空,将栈顶节点的 `tag` 标记为1(表示该节点已被访问),并将当前节点移动到栈顶节点的右子节点。
这段代码使用了栈和迭代的思想来实现二叉树的搜索。具体来说,它采用了深度优先搜索(DFS)的策略,但是通过迭代而不是递归的方式来遍历树的节点。
1. **栈的运用**:通过使用栈,代码模拟了递归调用时系统自动维护的调用栈。在每次访问一个节点时,将其信息(如节点指针和访问标记)压入栈中,以便后续可以回溯到该节点的父节点。
2. **迭代遍历**:通过循环结构,遍历整个二叉树。在每次循环迭代中,根据当前节点的情况进行相应的操作,包括压栈、出栈、移动指针等。
3. **深度优先搜索**:内层循环部分实现了深度优先搜索,即先尽可能深地访问左子树,直到找到目标值或者遍历到叶子节点,然后再回溯到父节点,访问右子树。