1、通过前序遍历建立二叉树
typedef struct TNode
{
int val;
TNode* left;
TNode* right;
}*BTree;
BTree Creatpre()
{
BTree T;
int a;
cin>>a;
if(a==0)
{
T=NULL;
}
else
{
T=new TNode;
T->val=a;
T->left=Creatpre();
T->right=Creatpre();
}
return T;
}
2、通过前序遍历序列+中序遍历序列建立二叉树 (重建二叉树)
牛客网上方法:需要额外的空间(O(n)),优点,代码方便易理解,不易出错
typedef struct TNode
{
int val;
TNode* left;
TNode* right;
}*BTree;
TNode* ReBuild(vector<int> pre,vector<int> in)
{
if(pre.size()==NULL||in.size()==NULL)
return NULL;
int len=pre.size();
//根据前序遍历和中序遍历特点,找到根节点
TNode *root=new TNode;
root->val=pre[0];
root->left=NULL;
root->right=NULL;
int rootflag=0;
for(int i=0;i<len;i++)
{
if(in[i]==pre[0])
{
rootflag=i;
}
}
//建立四个顺序表,分别存储左右子树
vector<int> preleft,preright,inleft,inright;
for(int i=0;i<rootflag;i++)
{
preleft.push_back(pre[i+1]);
inleft.push_back(in[i]);
}
for(int i=rootflag+1;i<len;i++)
{
preright.push_back(pre[i]);
inright.push_back(in[i]);
}
root->left=ReBuild(preleft,inleft);
root->right=ReBuild(preright,inright);
return root;
}
空间复杂度为O(1)的方法,利用指针
TNode* BuildFun(int *preOrder, int *inOrder, int length)
{
if (preOrder == NULL || inOrder == NULL || length <= 0) return NULL;
//新建结点,当前先序序列第一个元素为根结点
int root_val = preOrder[0];
TNode *root = new TNode();
root->val=preOrder[0];
//初始化左右子树参数
int leftLength = 0;
int rightLength = 0;
//在中序序列中找到根节点的位置(必存在)
for (int i = 0; i < length; i++)
{
if (inOrder[i] == root_val)
{
leftLength = i;
rightLength = length - i - 1;
break;
}
}
//中序序列中,根节点左边的为左子树,右边的为右子树
int *leftPre = preOrder + 1;
int *leftIn = inOrder;
int *rightPre = preOrder + leftLength + 1;
int *rightIn = inOrder + leftLength + 1;
//递归构建左右子树
root->left = BuildFun(leftPre, leftIn, leftLength);
root->right = BuildFun(rightPre, rightIn, rightLength);
return root;
}
3、中序+后序重建二叉树
后序遍历的最后一个遍历的往往是根节点,类似上述方法
TNode* BuildFun(int *inOrder, int *lastOrder, int length)
{
if (lastOrder == NULL || inOrder == NULL || length <= 0) return NULL;
int rootval=lastOrder[length-1];
TNode* root=new TNode;
root->left=NULL;
root->right=NULL;
root->val=rootval;
int leftLength = 0;
int rightLength = 0;
//在中序序列中找到根节点的位置(必存在)
for (int i = 0; i < length; i++)
{
if (inOrder[i] == rootval)
{
leftLength = i;
rightLength = length - i - 1;
break;
}
}
int *leftlast=lastOrder;
int *rightlast=lastOrder + leftLength ;
int *leftIn = inOrder;
int *rightIn = inOrder + leftLength + 1;
root->left = BuildFun(leftIn,leftlast,leftLength);
root->right = BuildFun(rightIn,rightlast,rightLength);
return root;
}
全部代码:
#include<iostream>
#include<vector>
using namespace std;
typedef struct TNode
{
int val;
TNode* left;
TNode* right;
}*BTree;
BTree Creatpre()
{
BTree T;
int a;
cin>>a;
if(a==0)
{
T=NULL;
}
else
{
T=new TNode;
T->val=a;
T->left=Creatpre();
T->right=Creatpre();
}
return T;
}
void PreTraverse(BTree T)
{
if(T==NULL)
{
return ;
}
cout<<T->val<<" ";
PreTraverse(T->left);
PreTraverse(T->right);
}
void MidTraverse(BTree T)
{
if(T==NULL)
{
return ;
}
MidTraverse(T->left);
cout<<T->val<<" ";
MidTraverse(T->right);
}
void LastTraverse(BTree T)
{
if(T==NULL)
{
return ;
}
LastTraverse(T->left);
LastTraverse(T->right);
cout<<T->val<<" ";
}
//二叉树的重建,前序+中序
TNode* ReBuild(vector<int> pre,vector<int> in)
{
if(pre.size()==NULL||in.size()==NULL)
return NULL;
int len=pre.size();
//根据前序遍历和中序遍历特点,找到根节点
TNode *root=new TNode;
root->val=pre[0];
root->left=NULL;
root->right=NULL;
int rootflag=0;
for(int i=0;i<len;i++)
{
if(in[i]==pre[0])
{
rootflag=i;
}
}
vector<int> preleft,preright,inleft,inright;
for(int i=0;i<rootflag;i++)
{
preleft.push_back(pre[i+1]);
inleft.push_back(in[i]);
}
for(int i=rootflag+1;i<len;i++)
{
preright.push_back(pre[i]);
inright.push_back(in[i]);
}
root->left=ReBuild(preleft,inleft);
root->right=ReBuild(preright,inright);
return root;
}
TNode* BuildFun(int *preOrder, int *inOrder, int length)
{
if (preOrder == NULL || inOrder == NULL || length <= 0) return NULL;
//新建结点,当前先序序列第一个元素为根结点
int root_val = preOrder[0];
TNode *root = new TNode();
root->val=preOrder[0];
//初始化左右子树参数
int leftLength = 0;
int rightLength = 0;
//在中序序列中找到根节点的位置(必存在)
for (int i = 0; i < length; i++)
{
if (inOrder[i] == root_val)
{
leftLength = i;
rightLength = length - i - 1;
break;
}
}
//中序序列中,根节点左边的为左子树,右边的为右子树
int *leftPre = preOrder + 1;
int *leftIn = inOrder;
int *rightPre = preOrder + leftLength + 1;
int *rightIn = inOrder + leftLength + 1;
//递归构建左右子树
root->left = BuildFun(leftPre, leftIn, leftLength);
root->right = BuildFun(rightPre, rightIn, rightLength);
return root;
}
//中序+后续
TNode* BuildFun(int *inOrder, int *lastOrder, int length)
{
if (lastOrder == NULL || inOrder == NULL || length <= 0) return NULL;
int rootval=lastOrder[length-1];
TNode* root=new TNode;
root->left=NULL;
root->right=NULL;
root->val=rootval;
int leftLength = 0;
int rightLength = 0;
//在中序序列中找到根节点的位置(必存在)
for (int i = 0; i < length; i++)
{
if (inOrder[i] == rootval)
{
leftLength = i;
rightLength = length - i - 1;
break;
}
}
int *leftlast=lastOrder;
int *rightlast=lastOrder + leftLength ;
int *leftIn = inOrder;
int *rightIn = inOrder + leftLength + 1;
root->left = BuildFun(leftIn,leftlast,leftLength);
root->right = BuildFun(rightIn,rightlast,rightLength);
return root;
}
int main()
{
int arr[8]={1,2,4,7,3,5,6,8};
int brr[8]={4,7,2,1,5,3,8,6};
int crr[8]={7,4,2,5,8,6,3,1};
vector<int> pre(arr,arr+8);
vector<int> in(brr,brr+8);
BTree T;
//ReBuild(pre,in);
T=BuildFun(brr,crr,8);
cout<<"一个二叉树创建:"<<endl;
//T=Creatpre();
PreTraverse(T);
cout<<endl;
//MidTraverse(T);
//cout<<endl;
//LastTraverse(T);
//cout<<endl;
return 0;
}