二叉树的相关操作
二叉树的相关操作一般要借助递归或者栈、队列来实现。通过二叉树了解递归是一个不错的手段。
1. 二叉树的前、中、后、层序遍历
// 前序遍历
void PreOrderTraverse(TreeNode *root)
{
if (root == NULL) return;
cout << root->value << " ";
PreOrderTraverse(root->left);
PreOrderTraverse(root->right);
}
// 中序遍历
void InOrderTraverse(TreeNode *root)
{
if (root == NULL) return;
InOrderTraverse(root->left);
cout << root->value << " ";
InOrderTraverse(root->right);
}
// 后续遍历
void PostOrderTraverse(TreeNode *root)
{
if (root == NULL) return;
PostOrderTraverse(root->left);
PostOrderTraverse(root->right);
cout << root->value << " ";
}
// 层序遍历
void LayerTraverse(vector<TreeNode *> layer)
{
if (layer.size() <= 0) return;
vector<TreeNode *> nextLayer;
vector<TreeNode *>::iterator it = layer.begin();
while (it != layer.end())
{
cout << (*it)->value << " ";
if ((*it)->left != NULL) nextLayer.push_back((*it)->left);
if ((*it)->right != NULL) nextLayer.push_back((*it)->right);
it++;
}
LayerTraverse(nextLayer);
}
2. 二叉树的高、宽
深度优先取树高、广度优先取树宽
// 深度优先求树高
int TreeHeight(TreeNode *root)
{
if (root == NULL) return 0;
int leftHeight = TreeHeight(root->left);
int rightHeight = TreeHeight(root->right);
return (leftHeight > rightHeight? leftHeight: rightHeight) + 1;
}
// 广度优先取树宽
int TreeWidth(vector<TreeNode *> layer)
{
if (layer.size() <= 0) return 0;
vector<TreeNode *> nextLayer;
vector<TreeNode *>::iterator it = layer.begin();
while (it != layer.end())
{
if ((*it)->left != NULL) nextLayer.push_back((*it)->left);
if ((*it)->right != NULL) nextLayer.push_back((*it)->right);
it++;
}
int maxWidth = TreeWidth(nextLayer);
return maxWidth > layer.size()? maxWidth: layer.size();
}
3. 二叉树的镜面转换
// 通过递归方式实现镜面翻转
// 1. 先保证后续节点已经翻转
// 2. 再翻转根节点的直系子节点
void MirrorReverse(TreeNode *root)
{
if (root == NULL) return;
MirrorReverse(root->left);
MirrorReverse(root->right);
TreeNode *tmp = root->left;
root->left = root->right;
root->right = tmp;
}
4. 二叉搜索树转双向链表
题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。比如输入下图中左边儿茶搜索树,则输出转换后的排序双向链表。
10
/ \
6 14
/ \ / \
4 8 12 16
4=6=8=10=12=14=16
// 将排序树转化成链表
// 相当于对其进行中序遍历
void Tree2LinkList(TreeNode *root, TreeNode **linkListTail)
{
if (root == NULL) return;
Tree2LinkList(root->left, linkListTail);
root->left = (*linkListTail);
if (*linkListTail != NULL)
(*linkListTail)->right = root;
(*linkListTail) = root;
Tree2LinkList(root->right, linkListTail);
}
// 调用
TreeNode* pLastNodeInList=NULL;
Tree2LinkList(root, &pLastNodeInList);
while (pLastNodeInList->left != NULL)
pLastNodeInList = pLastNodeInList->left;
while (pLastNodeInList != NULL)
{
cout << pLastNodeInList->value << " " << pLastNodeInList->left << " " << pLastNodeInList->right << endl;
pLastNodeInList = pLastNodeInList->right;
}