这一篇博客我总结一下部分二叉树的基本操作:
1、根据数组递归创建二叉树
2、递归实现前序遍历
3、递归实现中序遍历
4、递归实现后序遍历
5、前序,中序和后序的非递归实现
6、两种方法实现层序遍历
7、递归实现求深度
8、递归实现求最远两个节点距离
9、递归实现查找节点
二叉树的这些递归实现都可以非递归实现
//头文件
typedef struct BinaryTreeNode
{
int _data;
BinaryTreeNode* _leftchild;
BinaryTreeNode* _rightchild;
}BinaryTreeNode,*pBinaryTreeNode;
typedef struct BinaryTree
{
BinaryTreeNode *_root;
}BinaryTree,*pBinaryTree;
BinaryTreeNode* BuyTreeNode(int data)
{
BinaryTreeNode* pnewNode=(BinaryTreeNode*)malloc(sizeof(BinaryTreeNode));
if(pnewNode==NULL)
{
printf("memory is out\n");
exit(EXIT_FAILURE);
}
pnewNode->_data=data;
pnewNode->_leftchild=NULL;
pnewNode->_rightchild=NULL;
return pnewNode;
}
接下来我们看第一个实现,根据数组递归创建二叉树,‘#’表示要创建空节点,数组以前序遍历给出,同样我们创建也是根据前序遍历实现
BinaryTreeNode* RCreatBinaryTreeByPeorderTraversal(const int arr[],const int size,int& index,const int k)
{
BinaryTreeNode* pnewNode=NULL;
if(arr[index]!=k&&index<size)
{
pnewNode=BuyTreeNode(arr[index]);
pnewNode->_leftchild=RCreatBinaryTreeByPeorderTraversal(arr,size,++index,k);
pnewNode->_rightchild=RCreatBinaryTreeByPeorderTraversal(arr,size,++index,k);
}
return pnewNode;
}
注意这里的inde要用引用形式传到函数里,因为不管他在那一层递归里,我们需要不断使下标往前走,因此每一层对index的++ 都要真正的改变其值。
而且这里偶们最好对一些固定不变的参数加const,防止其值意外地被我们改变。
前序遍历的特点就是先打印根节点的值,再打印左孩子节点的值,最后打印右孩子节点的值。
//递归版本
void RPreOrder(BinaryTreeNode* root)
{
if(root==NULL)
return;
printf("%d\n",root->_data);
RPreOrder(root->_leftchild);
RPreOrder(root->_rightchild);
}
中序遍历是先打印左节点,再打印根节点,最后打印右节点
//递归版本
void RInOrder(BinaryTreeNode* root)
{
if(root==NULL)
return ;
RInOrder(root->_leftchild);
printf("%d\n",root->_data);
RInOrder(root->_rightchild);
}
后序遍历是先打印左节点,再打印右节点,最后打印根节点
//递归版本
void RPostOrder(BinaryTreeNode* root)
{
if(root==NULL)
return ;
RPostOrder(root->_leftchild);
if(root->_rightchild)
{
RPostOrder(root->_rightchild);
}
printf("%d\n",root->_data);
}
以上都是递归实现,下面贴出来非递归版本
void PreOrder(BinaryTreeNode* root)
{
BinaryTreeNode* pcurNode=NULL;
stack<BinaryTreeNode*> s;
assert(root);
s.push(root);
while(!s.empty())
{
pcurNode=s.top();
s.pop();
printf("%d\n",pcurNode->_data);
if(pcurNode->_rightchild)
{
s.push(pcurNode->_rightchild);
}
if(pcurNode->_leftchild)
{
s.push(pcurNode->_leftchild);
}
}
}
void InOrder(BinaryTreeNode* root)
{
BinaryTreeNode* pcurNode=root;
BinaryTreeNode* top=NULL;
stack<BinaryTreeNode*> s;
assert(root);
while(pcurNode||!s.empty())
{
while(pcurNode)
{
s.push(pcurNode);
pcurNode=pcurNode->_leftchild;
}
top=s.top();
s.pop();
printf("%d\n",top->_data);
pcurNode=top->_rightchild;
}
}
void PostOrder(BinaryTreeNode* root)
{
stack<BinaryTreeNode*> s;
BinaryTreeNode* pcurNode=root;
BinaryTreeNode* top=NULL;
BinaryTreeNode* pre=NULL;
assert(root);
while(pcurNode||!s.empty())
{
while(pcurNode)
{
s.push(pcurNode);
pcurNode=pcurNode->_leftchild;
}
top=s.top();
if(top->_rightchild==NULL||top->_rightchild==pre)
{
cout<<top->_data<<endl;
pre=top;
s.pop();
}
else
{
pcurNode=top->_rightchild;
}
}
}
下面我们实现层序遍历,层序遍历我用的是队列,当然我们以前做过一道题是用两个栈实现一个队列,所以这里我借用一下,可以用两个栈实现层序遍历
void LevelOrder_ByStack(BinaryTreeNode* root)
{
stack<BinaryTreeNode*> stack_1;
stack<BinaryTreeNode*> stack_2;
BinaryTreeNode* pcurNode=NULL;
stack_1.push(root);
if(root!=NULL)
{
while(!stack_1.empty() || !stack_2.empty())
{
while(!stack_1.empty())
{
printf("%d\n",stack_1.top()->_data);
stack_2.push(stack_1.top());
stack_1.pop();
}
while(!stack_2.empty())
{
pcurNode=stack_2.top();
if(pcurNode->_rightchild!=NULL)
stack_1.push(pcurNode->_rightchild);
if(pcurNode->_leftchild!=NULL)
stack_1.push(pcurNode->_leftchild);
stack_2.pop();
}
}
}
}
void LevelOrder_ByQueue(BinaryTreeNode* root)
{
BinaryTreeNode* pcurNode=NULL;
queue<BinaryTreeNode*> q;
assert(root);
q.push(root);
while(!q.empty())
{
pcurNode=q.front();
printf("%d\n",pcurNode->_data);
if(pcurNode->_leftchild)
{
q.push(pcurNode->_leftchild);
}
if(pcurNode->_rightchild)
{
q.push(pcurNode->_rightchild);
}
q.pop();
}
}
递归实现求深度
int Depth(BinaryTreeNode* root,int &depth)
{
if(root==NULL)
return 0;
int leftdepth=Depth(root->_leftchild,depth);
int rightdepth=Depth(root->_rightchild,depth);
return leftdepth>rightdepth?leftdepth+1:rightdepth+1;
}
递归实现求最远两个节点距离
int GetFastTwoNode(BinaryTreeNode* root,int &distance)
{
if(root==NULL)
return 0;
int leftdepth=GetFastTwoNode(root->_leftchild,distance);
int rightdepth=GetFastTwoNode(root->_rightchild,distance);
if((leftdepth+rightdepth)>distance)
distance=leftdepth+rightdepth;
return leftdepth>rightdepth?leftdepth+1:rightdepth+1;
}
递归实现查找节点
BinaryTreeNode* FindNode(BinaryTreeNode* root,const int& key)
{
if(root==NULL)
return NULL;
if(root->_data==key)
return root;
BinaryTreeNode* key_Node=FindNode(root->_leftchild,key);
if(key_Node==NULL)
key_Node=FindNode(root->_rightchild,key);
return key_Node;
}