前言
保存一下自己对二叉树从根节点到r所指节点之间的路径并输出算法的理解。
在这里偷懒了,没有调自己的栈的api函数,用的stl里的栈。不过无伤大雅,重要的是思想。
对于二叉树从根节点到r所指节点之间的路径的算法,首先要明白是先找到r所指的节点,然后不断出栈,这就有点类似与先输出子节点再输出父节点,因此该算法的模型即为二叉树的非递归的后序遍历。
这里虽然用了stl,但主要还是以C/C++为主。
思路
1.先递归建树
//先序递归建树,以'.'表示NULL
void PreOrderCreateTree(BiTree* bt) {
ElemType temp;
cin >> temp;
if (temp == '.') {
(*bt) == NULL;
}
else {
Node* s = (Node*)malloc(sizeof(Node));
s->data = temp;
s->lchild = s->rchild = NULL;
*bt = s;
PreOrderCreateTree(&(*bt)->lchild);
PreOrderCreateTree(&(*bt)->rchild);
}
return;
}
2.为r节点写按值寻找的算法
//按值查找二叉树,返回其节点。
void SearchTree(BiTree bt, ElemType key, Node** p) {
if (bt == NULL) {
return;
}
else {
//如果找到key,那么就修改p指针,否则p指针一直为NULL;
if (bt->data == key) {
*p = bt;
}
else {
SearchTree(bt->lchild, key, p);
SearchTree(bt->rchild, key, p);
}
}
}
3.路径输出算法
以二叉树的非递归的后序遍历的模板,当出栈元素为r节点时,弹空栈。
if (tmp == p) {
while (!S.empty()) {
BiTreeNode* pop = S.top();
printf("%c ", pop->data);
S.pop();
}
return;
}
else {
pre = cur;
S.pop();
cur = NULL;
}
4.测试结果
完整代码如下
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<stack>
#define ElemType char
using namespace std;
//二叉树的存储结构
typedef struct Node {
ElemType data;
struct Node* lchild;
struct Node* rchild;
}Node, * BiTree;
//先序递归建树,以'.'表示NULL
void PreOrderCreateTree(BiTree* bt) {
ElemType temp;
cin >> temp;
if (temp == '.') {
(*bt) == NULL;
}
else {
Node* s = (Node*)malloc(sizeof(Node));
s->data = temp;
s->lchild = s->rchild = NULL;
*bt = s;
PreOrderCreateTree(&(*bt)->lchild);
PreOrderCreateTree(&(*bt)->rchild);
}
return;
}
//按值查找二叉树,返回其节点。
void SearchTree(BiTree bt, ElemType key, Node** p) {
if (bt == NULL) {
return;
}
else {
//如果找到key,那么就修改p指针,否则p指针一直为NULL;
if (bt->data == key) {
*p = bt;
}
else {
SearchTree(bt->lchild, key, p);
SearchTree(bt->rchild, key, p);
}
}
}
//二叉树从根节点到r所指节点之间的路径并输出算法
void Path(BiTree bt, Node* r) {
if (bt == NULL) {
return;
}
Node* node = bt;
Node* pre = NULL;
stack<Node*>S;
while (node != NULL || !S.empty()) {
if (node != NULL) {
S.push(node);
node = node->lchild;
}
else {
Node* top = S.top();
if (top->rchild == NULL || top->rchild == pre) {
//如果找到r指针,那么直接弹栈直至栈空即可。否则按正常弹栈。
if (top == r) {
while (!S.empty()) {
Node* tmp = S.top();
printf("%c ", tmp->data);
S.pop();
}
return;
}
else {
pre = top;
S.pop();
node = NULL;
}
}
else {
node = top->rchild;
}
}
}
}
void test() {
BiTree bt = NULL;
PreOrderCreateTree(&bt);
Node* p = NULL;
SearchTree(bt, 'E', &p);
Path(bt, p);
return;
}
int main() {
test();/*测试用例 ABD..E..CF... */
//输出E B A
return 0;
}