二叉树的创建,遍历

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhuizhuzijidemenglsy/article/details/83314831

 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;
}


猜你喜欢

转载自blog.csdn.net/zhuizhuzijidemenglsy/article/details/83314831
今日推荐