根据前序遍历和中序遍历构建二叉树
#include <iostream>
#include <vector>
using namespace std;
struct Node
{
Node* pLeft;
Node* pRight;
char chValue;
Node(char ch) : chValue(ch), pLeft(NULL), pRight(NULL){}
};
void Rebuild(char* pPreOrder, char* pInOrder, int nTreeLen, Node** pRoot)
{
/*
pPreOrder:以null为结尾的前序遍历结果的字符串数组
pInOrder: 以null为结尾的中序遍历结果的字符串数组
nTreeLen: 树的长度
pRoot: 返回node**类型,根据前序和中序遍历结构重构树的根节点
*/
//检查边界条件
if (pPreOrder == NULL || pInOrder == NULL)
{
return;
}
//获得前序遍历的第一个节点
Node* pTemp = new Node(*pPreOrder);
if (*pRoot == NULL)
{
*pRoot = pTemp;
}
//如果树的长度是1,那么已经到了最后一个节点
if (nTreeLen == 1)
{
return;
}
//寻找子树长度
char* pOrgInOrder = pInOrder;
char* pLeftEnd = pInOrder;
int nTempLen = 0;
//寻找左子树的结尾
while (*pPreOrder != *pLeftEnd)
{
if (pPreOrder == NULL || pLeftEnd == NULL)
{
return;
}
nTempLen++;
//记录临时长度,避免溢出
if (nTempLen > nTreeLen)
{
break;
}
pLeftEnd++;
}
//寻找左子树的长度
int nLeftLen = 0;
nLeftLen = (int)(pLeftEnd - pOrgInOrder);
//寻找右子树的长度
int nRightLen = 0;
nRightLen = nTreeLen - nLeftLen - 1;
//重建左子树
if (nLeftLen>0)
{
Rebuild(pPreOrder + 1, pInOrder, nLeftLen, &((*pRoot)->pLeft));
}
//重建右子树
if (nRightLen > 0)
{
Rebuild(pPreOrder + nLeftLen + 1, pInOrder + nLeftLen + 1, nRightLen, &((*pRoot)->pRight));
}
}
void PreOrderTraversal(Node* root, vector<char> &data)
{
/*前序遍历*/
if (root == NULL)
{
return;
}
data.push_back(root->chValue);
PreOrderTraversal(root->pLeft, data);
PreOrderTraversal(root->pRight, data);
}
void InOrderTraversal(Node* root, vector<char> &data)
{
/*中序遍历*/
if (root == NULL)
{
return;
}
PreOrderTraversal(root->pLeft, data);
data.push_back(root->chValue);
PreOrderTraversal(root->pRight, data);
}
void PostOrderTraversal(Node* root, vector<char> &data)
{
/*后序遍历*/
if (root == NULL)
{
return;
}
PostOrderTraversal(root->pLeft, data);
PostOrderTraversal(root->pRight, data);
data.push_back(root->chValue);
}
void LayerTraversal(Node* root)
{
//分层访问二叉树
vector<Node *> vec;
if (root == NULL)
{
return;
}
vec.push_back(root);
int cur = 0;
int last = 1;
while (cur < vec.size())
{
last = vec.size();
while (cur < last)
{
cout << vec[cur]->chValue << " ";
if (vec[cur]->pLeft != NULL)
{
vec.push_back(vec[cur]->pLeft);
}
if (vec[cur]->pRight != NULL)
{
vec.push_back(vec[cur]->pRight);
}
cur++;
}
cout << endl;
}
}
int main(int argc,char* argv[])
{
const int testLen = 6;
char szPreOrder[testLen] = { 'a', 'b', 'd', 'c', 'e', 'f' };
char szInOrder[testLen] = { 'd', 'b', 'a', 'e', 'c', 'f' };
vector<char> szPostOrder;
Node* pRoot = NULL;
Rebuild(szPreOrder, szInOrder, testLen, &pRoot);
LayerTraversal(pRoot);
PostOrderTraversal(pRoot, szPostOrder);
for (auto i : szPostOrder)
{
cout << i << " ";
}
cout << endl;
system("pause");
return 0;
}
这是一个关于二叉树的大的程序,首先我们要知道二叉树的三种遍历:前序遍历、中序遍历、后序遍历,其中,前序遍历的顺序是根左右;中序遍历的顺序是左根右;后序遍历的顺序是左右根。可以得到简单的函数
前序遍历:
void PreOrderTraversal(Node* root, vector<char> &data)
{
/*前序遍历*/
if (root == NULL)
{
return;
}
data.push_back(root->chValue);
PreOrderTraversal(root->pLeft, data);
PreOrderTraversal(root->pRight, data);
}
中序遍历
void InOrderTraversal(Node* root, vector<char> &data)
{
/*中序遍历*/
if (root == NULL)
{
return;
}
PreOrderTraversal(root->pLeft, data);
data.push_back(root->chValue);
PreOrderTraversal(root->pRight, data);
}
后序遍历
void PostOrderTraversal(Node* root, vector<char> &data)
{
/*后序遍历*/
if (root == NULL)
{
return;
}
PostOrderTraversal(root->pLeft, data);
PostOrderTraversal(root->pRight, data);
data.push_back(root->chValue);
}
二叉树的分层遍历
void LayerTraversal(Node* root)
{
//分层访问二叉树
vector<Node *> vec;
if (root == NULL)
{
return;
}
vec.push_back(root);
int cur = 0;
int last = 1;
while (cur < vec.size())
{
last = vec.size();
while (cur < last)
{
cout << vec[cur]->chValue << " ";
if (vec[cur]->pLeft != NULL)
{
vec.push_back(vec[cur]->pLeft);
}
if (vec[cur]->pRight != NULL)
{
vec.push_back(vec[cur]->pRight);
}
cur++;
}
cout << endl;
}
}
根据前序遍历和中序遍历得到二叉树:
void Rebuild(char* pPreOrder, char* pInOrder, int nTreeLen, Node** pRoot)
{
/*
pPreOrder:以null为结尾的前序遍历结果的字符串数组
pInOrder: 以null为结尾的中序遍历结果的字符串数组
nTreeLen: 树的长度
pRoot: 返回node**类型,根据前序和中序遍历结构重构树的根节点
*/
//检查边界条件
if (pPreOrder == NULL || pInOrder == NULL)
{
return;
}
//获得前序遍历的第一个节点
Node* pTemp = new Node(*pPreOrder);
if (*pRoot == NULL)
{
*pRoot = pTemp;
}
//如果树的长度是1,那么已经到了最后一个节点
if (nTreeLen == 1)
{
return;
}
//寻找子树长度
char* pOrgInOrder = pInOrder;
char* pLeftEnd = pInOrder;
int nTempLen = 0;
//寻找左子树的结尾
while (*pPreOrder != *pLeftEnd)
{
if (pPreOrder == NULL || pLeftEnd == NULL)
{
return;
}
nTempLen++;
//记录临时长度,避免溢出
if (nTempLen > nTreeLen)
{
break;
}
pLeftEnd++;
}
//寻找左子树的长度
int nLeftLen = 0;
nLeftLen = (int)(pLeftEnd - pOrgInOrder);
//寻找右子树的长度
int nRightLen = 0;
nRightLen = nTreeLen - nLeftLen - 1;
//重建左子树
if (nLeftLen>0)
{
Rebuild(pPreOrder + 1, pInOrder, nLeftLen, &((*pRoot)->pLeft));
}
//重建右子树
if (nRightLen > 0)
{
Rebuild(pPreOrder + nLeftLen + 1, pInOrder + nLeftLen + 1, nRightLen, &((*pRoot)->pRight));
}
}