二叉树从根节点到r所指节点之间的路径并输出算法【C/C++】


前言

保存一下自己对二叉树从根节点到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;
}

猜你喜欢

转载自blog.csdn.net/qq_45400167/article/details/125798880