Files
Learn-Algorithms/9 Algorithms Job Interview/二叉树.md
T
2021-03-18 21:24:06 +08:00

5.2 KiB

问题涉及有:

  • 遍历
  • 翻转
  • 子树

把二元查找树转变成排序的双向链表

输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。

  10
  / \
 6   14
/\   / \
4 8 12 16

转换成双向链表 4=6=8=10=12=14=16

首先我们定义的二元查找树 节点的数据结构如下:

 struct BSTreeNode
{
  int m_nValue; // value of node
  BSTreeNode *m_pLeft; // left child of node
  BSTreeNode *m_pRight; // right child of node
};

分析:题目要求不能创建任何节点,也就是只能调整各个节点的指向 思路一:

在二元树中找出和为某一值的所有路径

题目:输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。

例如 输入整数22和如下二元树

  10   
  / \   
  5 12   
  /\   
  4 7

则打印出两条路径:10, 12 和 10, 5, 7 。

二元树节点的数据结构定义为:

struct BinaryTreeNode // a node in the binary tree
{
  int m_nValue; // value of node
  BinaryTreeNode *m_pLeft; // left child of node
  BinaryTreeNode *m_pRight; // right child of node
};
  1. 累加当前节点,累加和大于给定值
  2. 不为叶节点,左子树入栈

判断整数序列是不是二元查找树的后序遍历结果

题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。 如果是返回true,否则返回false。 例如输入5、7、6、9、11、10、8,由于这一整数序列是如下树的后序遍历结果:

    8
  /  \
  6   10
  /\  / \
  5 7 9 11

因此返回true。如果输入7、4、6、5,没有哪棵树的后序遍历的结果是这个序列,因此返回false。

一棵排序二叉树,令 f=(最大值+最小值)/2,设计一个算法,找出距离f值最近、大于f值的结点。

复杂度如果是O(n2)则不得分。

二叉树翻转

输入一颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找树中,左子树的结点都大于右子树的结点。用递归和循环两种方法完成树的镜像转换。例

如输入:

   8
  / \
  6 10
 /\ / \
5 7 9 11

输出:

   8
  / \
 10  6
 /\  /\
11 9 7 5

定义二元查找树的结点为:

struct BSTreeNode // a node in the binary search tree (BST)
{
  int m_nValue; // value of node
  BSTreeNode *m_pLeft; // left child of node
  BSTreeNode *m_pRight; // right child of node
};

按层打印二叉树

输入一颗二元树,从上往下按层打印树的每个结点,同一层中按照从左往右的顺序打印。
例如输入

   8
  /\
 6  10
/ \ /\
5 7 9 11

输出8 6 10 5 7 9 11

二元树的深度

题目:输入一棵二元树的根结点,求该树的深度.从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。 例如:输入二元树:


                                     10
                                  /     \
                                 6        14
                              /         /   \
                             4         12     16

输出该树的深度3。

二元树的结点定义如下:

struct SBinaryTreeNode // a node of the binary tree
{
      int               m_nValue; // value of node
      SBinaryTreeNode  *m_pLeft;  // left child of node
      SBinaryTreeNode  *m_pRight; // right child of node
};

分析:这道题本质上还是考查二元树的遍历。对于一颗完全二叉树,要求给所有节点加上一个pNext指针,指向同一层的相邻节点;如果当前节点已经是该层的最后一个节点,则将pNext指针指向NULL;给出程序实现,并分析时间复杂度和空间复杂度。

把一个有序整数数组放到二叉树中?

分析:本题考察二叉搜索树的建树方法,简单的递归结构。

关于树的算法设计一定要联想到递归,因为树本身就是递归的定义。 而,学会把递归改称非递归也是一种必要的技术。 毕竟,递归会造成栈溢出,关于系统底层的程序中不到非不得以最好不要用。 但是对某些数学问题,就一定要学会用递归去解决。

二叉树两个结点的最低共同父结点

设计一个算法,找出二叉树上任意两个结点的最近共同父结点。复杂度如果是O(n2)则不得分

二叉树的结点定义如下:

struct TreeNode
{
  int m_nvalue;
  TreeNode* m_pLeft;
  TreeNode* m_pRight;
};

输入二叉树中的两个结点,输出这两个结点在数中最低的共同父结点。

分析:求数中两个结点的最低共同结点是面试中经常出现的一个问题。这个问题至少有两个变种。

俩种方法实现二叉树的前序遍历。

递归和非递归

恢复树结构

有一棵树(树上结点为字符串或者整数),请写代码将树的结构和数据写到一个文件中,并能通过读取该文件恢复树结构。