利用栈容器可以实现二叉树的非递归遍历
首先将每个节点都设置一个标志,默认标志为假,根据节点的的状态进行如下流程。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"seqstack.h"
//树的节点类型
typedef struct node
{
int flag;
//数据域
char ch;
//指针域
struct node *lchild;
struct node *rchild;
}NODE;
int main()
{
NODE nodeA = { 0,'A',NULL,NULL };
NODE nodeB = { 0,'B',NULL,NULL };
NODE nodeC = { 0,'C',NULL,NULL };
NODE nodeD = { 0,'D',NULL,NULL };
NODE nodeE = { 0,'E',NULL,NULL };
NODE nodeF = { 0,'F',NULL,NULL };
NODE nodeG = {0, 'G',NULL,NULL };
NODE nodeH = {0, 'H',NULL,NULL };
//建立关系
nodeA.lchild = &nodeB;
nodeA.rchild = &nodeF;
nodeB.rchild = &nodeC;
nodeC.lchild = &nodeD;
nodeC.rchild = &nodeE;
nodeF.rchild = &nodeG;
nodeG.lchild = &nodeH;
//初始化栈 (手动实现的栈)
SeqStack stack = Init_seqstack();
Push_SeqStack(stack,&nodeA);
while ( !IsEmpty_SeqStack(stack))
{
NODE *top = (NODE *)GetTop_SeqStack(stack);
Pop_SeqStack(stack);
if (top->flag == 1)
{
printf("%c ",top->ch);
continue;
}
top->flag = 1;
if(top->rchild != NULL)
Push_SeqStack(stack,top->rchild);
Push_SeqStack(stack,top);
if (top->lchild != NULL)
Push_SeqStack(stack,top->lchild);
}
system("pause");
return 0;
}
将代码稍作修改应用于LeetCode中的前中后非递归遍历二叉树
94 144 145(题号)
执行结果:通过显示详情
执行用时:0 ms, 在所有 C++ 提交中击败了100.00%的用户
内存消耗:8.1 MB, 在所有 C++ 提交中击败了90.71%的用户
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> v;
example(root, v);
return v;
}
void example(TreeNode *root, vector<int> &path){
stack<pair<TreeNode *, bool>> s;
s.push(make_pair(root, false));
bool flag;
while(!s.empty())
{
root = s.top().first;
flag = s.top().second;
s.pop();
if(root == NULL)
continue;
if(flag)
path.push_back(root->val);
else
{
//调整插入顺序即先中后序遍历 比如这里是后序遍历 按照后序遍历的左右根反着插入即可 依次类推
s.push(make_pair(root, true));
s.push(make_pair(root->right, false));
s.push(make_pair(root->left, false));
}
}
}
};
递归遍历,深度以及叶子节点数量求解
typedef struct _PTNode{
char ch;
struct _PTNode* lchild;
struct _PTNode* rchild;
}PTNode;
//递归遍历
void RecursionBiTree(PTNode* root){
if (root == NULL){
return; }
//printf("%c", root->ch); //先序遍历
RecursionBiTree(root->lchild);
printf("%c", root->ch); //中序遍历
RecursionBiTree(root->rchild);
//printf("%c", root->ch); //后序遍历
}
//求叶子结点数量
int leafNum = 0;
void RecursionBiTree(PTNode* root){
if (root == NULL){
return; }
if (!root->lchild && !root->rchild){
leafNum++;
}
RecursionLeafNumTree(root->lchild);
RecursionLeafNumTree(root->rchild);
}
//求二叉树深度
int RecursionTreeDepth(PTNode* root){
int depth = 0;
if (root == NULL){
return depth;
}
int ldepth = RecursionTreeDepth(root->lchild);
int rdepth = RecursionTreeDepth(root->rchild);
depth = ldepth >= rdepth ? ldepth + 1 : rdepth + 1;
return depth;
}
已知先序,中序遍历结果,重建二叉树 (剑指offer 面试题6)
先序的第一个元素是根节点,找到和这个根节点相同的中序的位置,这个位置左边是左子树,右边是右子树。重复以上步骤
class Solution
{
TreeNode buildTree(int[] preorder, int[] inorder)
{
return help(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
}
TreeNode help(int[] preorder,int l1,int r1,int[] inorder,int l2,int r2)
{
if(l1>r1||l2>r2) return null;//临界
int i =l2;
while(inorder[i]!=preorder[l1])//寻找根节点在中序的位置
{
i++;
}
TreeNode root = new TreeNode(preorder[l1]);
root.left = help(preorder,l1+1,l1+i-l2,inorder,l2,i-1);
root.right = help(preorder,l1+i-l2+1,r1,inorder,i+1,r2);
return root;
}
二叉树中和为某一值的路径
class Solution {
private:
vector<int> path;
vector<vector<int>> res;
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
dfs(root, sum);
return res;
}
void dfs(TreeNode* curr, int target)
{
if (curr != nullptr)
{
target -= curr->val;
path.push_back(curr->val);
if (target != 0 || curr->left != nullptr || curr->right != nullptr)
{
dfs(curr->left, target);
dfs(curr->right, target);
}
else
{
res.push_back(path);
}
path.pop_back();
}
}
};
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。
class Solution {
public:
Node *pre, *head;
Node* treeToDoublyList(Node* root)
{
if(root==NULL)
return NULL;
dfs(root);
head->left=pre;
pre->right=head;
return head;
}
void dfs(Node* cur)
{
if(cur==NULL)
return;
dfs(cur->left);
if(pre!=NULL)
pre->right=cur;
else
head=cur;
cur->left=pre;
pre=cur;
dfs(cur->right);
}
};