算法思想:
1. 使用后序遍历的非递归方法遍历二叉树。
2. 当访问到结点p时,说明从根节点到p所指结点之间的路径已经找到。
3. 在遍历过程中,使用一个辅助栈来保存遍历过程中的结点。
4. 每次遍历到一个结点时,将其入栈。
5. 若当前结点是叶子结点或者其右孩子已经被访问过,则该结点可以出栈。
6. 若出栈的结点是目标结点p,则辅助栈中保存的结点即为从根节点到p所指结点之间的路径。
算法实现:
#include <stdio.h>
#include <stdlib.h>
typedef struct BitNode {
int data;
struct BitNode* left;
struct BitNode* right;
} BiTree;
int FindPath(BiTree* root, BiTree* p) {
if (root == NULL || p == NULL) {
return 0;
}
// 定义辅助栈和指针变量
BiTree* stack[100]; // 假设栈最大容量为100
int top = -1;
BiTree* cur = root; // 当前结点
BiTree* prev = NULL; // 上一次访问的结点
while (cur != NULL || top != -1) {
// 遍历到左子树最底部,将遇到的结点入栈
while (cur != NULL) {
stack[++top] = cur;
cur = cur->left;
}
cur = stack[top]; // 获取栈顶结点
// 若当前结点是叶子结点或者其右孩子已经被访问过,则该结点可以出栈
if (cur->right == NULL || cur->right == prev) {
// 出栈的结点是目标结点p,结束遍历
if (cur == p) {
return 1;
}
top--;
prev = cur;
cur = NULL;
} else {
cur = cur->right; // 遍历右子树
}
}
return 0;
}
int main() {
// 创建二叉树
BiTree* root = (BiTree*)malloc(sizeof(BiTree));
root->data = 1;
BiTree* node1 = (BiTree*)malloc(sizeof(BiTree));
node1->data = 2;
BiTree* node2 = (BiTree*)malloc(sizeof(BiTree));
node2->data = 3;
root->left = node1;
root->right = node2;
node1->left = NULL;
node1->right = NULL;
node2->left = NULL;
node2->right = NULL;
BiTree* p = node2; // 给定结点p为node2
// 寻找路径
if (FindPath(root, p)) {
printf("Path found!\n");
} else {
printf("No path found!\n");
}
return 0;
}