二叉树经典面试题

二叉树的结点类型如下:

typedef struct BtNode
{
    BtNode *leftchild;
    BtNode *rightchild;
    ElemType data;
}BtNode, *BinaryTree;

1. 给你一颗普通的二叉树,求二叉树中最远的两个节点的距离

   分析:

   1、如果具有最远距离的两个结点之间的路径经过根结点,则最远距离就是这个根节点左边的深度加上根节点的右边的深度。

  2、如果具有最远距离的两个结点之间的路径不经过根节点,则最远距离的结点就在根节点的某一棵子树上的两个叶子结点。

  使用distance记录这个最远的距离。后序遍历二叉树中每一个结点,对于每一个结点先算出左边和右边的深度和然后与distance里面的数据进行比较,如果结果大于distance则更新distance的值。

int _GetFarDistance(BtNode* root,int &distance)
{
	if(root==NULL) return 0;
	int Left=_GetFarDistance(root->_left,distance);
	int Right=_GetFarDistance(root->_right,distance);
	if((Left+Right)>distance)
	{
		distance=Left+Right;
	}
	return Left>Right?Left+1:Right+1;
}


int GetFartherDistance(BtNode* root)
{
	assert(root);
	int distance=0;
	_GetFarDistance(root,distance);
	return distance; 
}

2. 由前序遍历和中序遍历重建二叉树(前序序列:1 2 3 4 5 6 - 中序序列:3 2 4 1 6 5)

  前序遍历的每一结点,都是当前子树的根节点,我们可以根据前序遍历的序列对中序遍历的序列进行划分。


int IsIndex(ElemType *is,ElemType x,int n)
{
	for (int i = 0;i<n;++i)
	{
		if (is[i] == x)
		{
			return i;
		}
	}
	return -1;
}
 
BtNode * CreatePI(ElemType *ps,ElemType *is,int n)
{
	BtNode *s = NULL;
	if (n > 0)
	{
		s = BuyNode();
		s->data = ps[0];
		int pos = IsIndex(is,ps[0],n);
		if (pos == -1)
		{
			exit(1);
		}
		s->leftChild = CreatePI(ps+1,is,pos);
		s->rightChild = CreatePI(ps+pos+1,is+pos+1,n-pos-1);
	}
	return s;
}
BtNode * CreateTreePI(ElemType *ps,ElemType *is,int n)
{
    if (ps == NULL || is == NULL || n < 1)
    {
        return NULL;
    }
    else
    {
        return  CreatePI(ps,is,n);
    }
}

3. 判断一棵树是否是完全二叉树

我们可以根据完全二叉树的定义,按照层序遍历一颗树,当遇到空结点时如果这棵树已经遍历完毕,则这棵树就是完全二叉树,如果遇到空结点的后面还有元素则这棵树就不是完全二叉树。

bool IsCompleteBinaryTree(BTNode* root)  //判断一颗二叉树是否是完全二叉树
{
	if (root == NULL)
		return false;
	queue<BTNode*> q;
	int flag = 0;
	q.push(root);
	while (!q.empty())
	{
		BTNode<int>* cur = q.front();
		q.pop();
		if (cur->_left)
		{
			if (flag)
				return false;
			q.push(cur->_left);
		}
		else
		{
			if (flag == 0)
				flag = 1;
		}
		if (cur->_right)
		{
			if (flag)
				return false;
			q.push(cur->_right);
		}
		else
		{
			if (flag == 0)
				flag = 1;
		}
	}

方法2:

        

什么是完全二叉树呢???

  如果一颗二叉树的只有最后两层结点的度能小于2,其余结点的度都等于2。且最后一层的结点从最左边依次排列。

思路:  若父节点不空,我们将二叉树左右孩子依次放入队列(空结点也放入队列),依次出队,遇到第一个空结点,我们判断后续队列中的节点是否为空,若空,则是完全二叉树。

    

bool Is_Comp_BinaryTree(BtNode *ptr)
{
	if (ptr == NULL) return true;
	queue<BtNode *> qu;
	qu.push(ptr);
	while (!qu.empty())
	{
		BtNode *p = qu.front(); qu.pop();
		if (p == NULL)
		{
			break;
		}
		qu.push(p->leftchild);
		qu.push(p->rightchild);
	}
	while (!qu.empty())
	{
		BtNode *p = qu.front(); qu.pop();
		if (p != NULL) return false;
	}
	return true;
}

 

4. 后序和中序序列创建二叉树 


int IsIndex(ElemType *is,ElemType x,int n)
{
	for (int i = 0;i<n;++i)
	{
		if (is[i] == x)
		{
			return i;
		}
	}
	return -1;
}
BtNode * CreateIL(ElemType *is,ElemType *ls,int n)
{
    BtNode *s = NULL;
    if (n > 0)
    {
        int pos = IsIndex(is,ls[n-1],n);
        if (pos == -1)
        {
            exit(1);
        }
        s = BuyNode();
        s->data = ls[n-1];
        s->leftChild = CreateIL(is,ls,pos);
        s->rightChild = CreateIL(is+pos+1,ls+pos,n-pos-1);
    }
    return s;
}
BtNode * CreateTreeIL(ElemType *is,ElemType *ls,int n)
{
    if (is == NULL || ls == NULL || n < 1)
    {
        return NULL;
    }
    else
    {
        return CreateIL(is,ls,n);
    }
}

5. 求两个节点的最近公共祖先

分析:

  求两个结点的最近公共祖先有两种情况。

  1、如果这两个结点不在一条线上,则它们就分别在最近的公共祖父的左右子树上。

  2、如果这两个结点在一条线上,则它们之中深度最前的就是他们的最近的公共祖先。

思路:

       给定一棵二叉树的头节点root,以及这棵二叉树的两个节点node1和node2,请返回node1和node2的最近公共祖先节点。我们可以后序遍历这棵树,用left记录左子树返回的结果,用right记录右子树返回的结果。

虽然是三种情况,但是不论是哪一种,只要返回left和right中不为空的就可以了

BTNode* _GetAncestor(BTNode root,BTNode node1,BTNode node2)
{
	if (root == NULL)
		return NULL;
	BTNode left = _GetAncestor(root->_left, node1, node2);
	BTNode right = _GetAncestor(root->_right, node1, node2);
	if (left&&right)
		return root;
	if (root == node1)
		return node1;
	if (root == node2)
		return node2;
	if (left == NULL&&right)
		return right;
	if (right == NULL&&left)
		return left;
	return NULL;
}

BTNode* GetAncestor(BTNode* root, BTNode* node1, BTNode* node2)
{
	assert(root);
	assert(node1);
	assert(node2);
	BTNode* parent = NULL;
	BTNode* left = NULL;
	BTNode* right = NULL;
	parent = _GetAncestor(root, node1, node2);
	return parent;
	​
}

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python二叉树面试题有很多种,以下是其中几个常见的面试题: 1. 二叉树的最大深度:这个问题要求计算给定二叉树的最大深度。可以使用递归的方法来解决,递归函数的定义是返回当前节点的深度,递归终止条件是节点为空时返回0,递归过程中比较左右子树的深度并返回较大值加1。时间复杂度为O(n),空间复杂度为O(n)。 2. 二叉树的前序遍历:这个问题要求按照前序遍历的顺序输出二叉树节点值。可以使用递归或迭代的方法来解决。递归方法的思路是先输出当前节点的值,然后递归遍历左子树,最后递归遍历右子树。迭代方法可以使用栈来辅助实现,把根节点压入栈中,然后循环弹出栈顶节点,输出其值,并将其右子节点和左子节点依次压入栈中。时间复杂度为O(n),空间复杂度为O(n)。 3. 二叉树的层序遍历:这个问题要求按照层序遍历的顺序输出二叉树节点值。可以使用队列来辅助实现。首先将根节点入队,然后循环直到队列为空,每次从队列中取出一个节点,输出其值,并将其左右子节点依次入队。时间复杂度为O(n),空间复杂度为O(n)。 以上是几个常见的Python二叉树面试题的解法,根据具体的问题要求和输入条件选择合适的解法即可。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【编程之路】面试必刷TOP101:二叉树系列(23-30,Python实现)](https://blog.csdn.net/be_racle/article/details/125531755)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [【面试题8】二叉树的下一个节点](https://download.csdn.net/download/weixin_38589168/14035034)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值