二叉树的先中后非递归遍历,以及树的高度和叶子节点求解等面试题

利用栈容器可以实现二叉树的非递归遍历

首先将每个节点都设置一个标志,默认标志为假,根据节点的的状态进行如下流程。
在这里插入图片描述

#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);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
04-26
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值