本博客目录
- 二叉树的先序、中序、后序遍历,递归和非递归
- 在二叉树中找到中序遍历的下一个节点
- 二叉树的序列化和反序列化
二叉树的先序、中序、后序遍历,递归和非递归
递归版本
//树的结构
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
}
//先序遍历
vector<int> preOrderRecur(TreeNode* head) {
vector<int> tmp;
if (head == NULL) {
return tmp;
}
return preOrderRecurCore(head, tmp);
}
vector<int> preOrderRecurCore(TreeNode* head, vector<int>& tmp){
if(head == NULL){
return tmp;
}
tmp.push_back(head->val);
preOrderRecur(head->left, tmp);
preOrderRecur(head->right, tmp);
return tmp;
}
//中序遍历
vector<int> inOrderRecur(TreeNode* head) {
vector<int> tmp;
if (head == NULL) {
return tmp;
}
return inOrderRecurCore(head, tmp);
}
vector<int> inOrderRecurCore(TreeNode* head, vector<int>& tmp){
if(head == NULL){
return tmp;
}
inOrderRecurCore(head->left, tmp);
tmp.push_back(head->val);
inOrderRecurCore(head->right, tmp);
return tmp;
}
//后序遍历
vector<int> posOrderRecur(TreeNode* head) {
vector<int> tmp;
if (head == NULL) {
return tmp;
}
return posOrderRecurCore(head, tmp);
}
vector<int> posOrderRecurore(TreeNode* head, vector<int>& tmp){
if(head == NULL){
return tmp;
}
posOrderRecurCore(head->left, tmp);
posOrderRecurCore(head->right, tmp);
tmp.push_back(tmp->val);
return tmp;
}
非递归版本
/*
要弄清楚先序遍历的实质
在递归版本中,每个节点会访问三次
用栈模拟递归情况
*/
vector<int> preOrderUnRecur(TreeNode* head) {
vector<int> tmp;
if(head == NULL){
return tmp;
}
stack<TreeNode*> res;
res.push(head);
while (!res.empty()) {
TreeNode* curNode = res.top();
res.pop();
tmp.push_back(curNode->val);
if (curNode->right != NULL) {
res.push(curNode->right);
}
if (curNode->left != NULL) {
res.push(curNode->left);
}
}
return tmp;
}
/*
中序遍历,就是一直压左子树,直到为空,打印,压右子树
用递归实现
*/
vector<int> inOrderUnRecur(TreeNode* head) {
vector<int> tmp;
if(head == NULL){
return tmp;
}
stack<TreeNode*> res;
while (!res.empty() || head != NULL) {
if (head != NULL) {
res.push(head);
head = head->left;
}
else {
head = res.top();
res.pop();
tmp.push_back(head->val);
head = head->right;
}
}
return tmp;
}
/*
后序遍历,
*/
vector<int> posOrderUnRecur(TreeNode* head) {
vector<int> tmp;
if(head == NULL){
return tmp;
}
stack<TreeNode*> s1;
stack<int> s2;
s1.push(head);
while (!s1.empty()) {
TreeNode* curNode = s1.top();
s1.pop();
s2.push(curNode->val);
if (curNode->left != NULL) {
s1.push(curNode->left);
}
if (curNode->right != NULL) {
s1.push(curNode->right);
}
}
while (!s2.empty()) {
tmp.push_back(s2.top());
s2.pop();
}
return tmp;
}
在二叉树中找到中序遍历的下一个节点
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
struct TreeLinkNode {
int val;
struct TreeLinkNode *left;
struct TreeLinkNode *right;
struct TreeLinkNode *next;
TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {
}
};
/*
有这么几种情况:
1.右子树存在:下一个节点就是右子树的最右节点
2.右子树不存在,该节点是父节点的左子树:下一个节点就是父节点
3.右子树不存在,该节点不是父节点的左子树,在往上找父节点,直到是父节点的左子树或者父节点为NULL返回
*/
class Solution {
public:
TreeLinkNode* GetNext(TreeLinkNode* pNode){
if(pNode == NULL){
return NULL;
}
if(pNode->right != NULL){
pNode = pNode->right;
while(pNode->left != NULL){
pNode = pNode->left;
}
return pNode;
}
while(pNode->next!= NULL){
TreeLinkNode* pRoot = pNode->next;
if(pRoot->left == pNode){
return pRoot;
}
pNode = pRoot;
}
return NULL;
}
};
二叉树的序列化和反序列化
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
class Solution {
public:
char* Serialize(TreeNode *root) {
if(root == NULL){
return NULL;
}
string str;
Serialize(root, str);
char* tmp = new char[str.length() + 1];
int i;
for(i = 0; i < str.length(); i++){
tmp[i] = str[i];
}
tmp[i] = '\0';
return tmp;
}
void Serialize(TreeNode* root, string& str){
if(root == NULL){
str += '#';
return;
}
string r = to_string(root->val);
str += r;
str += ',';
Serialize(root->left, str);
Serialize(root->right, str);
}
TreeNode* Deserialize(char *str) {
if(str == NULL){
return NULL;
}
TreeNode* root = decode(str);
return root;
}
TreeNode* decode(char* &str){
if(*str == '#'){
str++;
return NULL;
}
int num = 0;
while(*str != '\0' && *str != ','){
num = num * 10 + (*str - '0');
str++;
}
TreeNode* node = new TreeNode(num);
if(*str == '\0'){
return node;
}
else{
str++;
}
node->left = decode(str);
node->right = decode(str);
return node;
}
};
参考
牛客网左程云算法课