二叉树的操作
Posted 勇士后卫头盔哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的操作相关的知识,希望对你有一定的参考价值。
二叉树的属性操作
1.二叉树结点的数目
对于二叉树结点数目的计算需要用递归来解决,在node为根节点的二叉树中统计结点数目的递归公式如下所示
return 0; node == NULL
count(node)
count(node->left)+count(node->right)+1; node!=NULL;
代码如下:
int count(BTreeNode<T>* node)const
if(node == NULL)
return 0;
else
return count(node->l_pointer)+count(node->r_pointer)+1;
/*
可以简化为
return (node!=NULL)?(count(node->l_pointer)+count(node->r_pointer)+1):0;
*/
2.二叉树的高度
原理上是一样的,二叉树的高度也要用递归来求,获取node为根节点的二叉树的高度的递归公式如下所示,比较左子树和右子树高度的最大值加1就完成了
return 0; node==NULL;
height(node)
Maxheight(node->left),height(node->right)+1; node!=NULL;
代码实现
int height(BTreeNode<T>* node) const
if(node == NULL)
return 0;
else
int lh = height(node->l_pointer);
int rh = height(node->r_pointer);
return ((rh>lh)?rh:lh)+1;
3.树的度数
还是老套路使用递归来求解这个问题,递归公式如下所示
return 0; node == NULL
degree(node)
Max
degree(node->left),
degree(node->right), node!=NULL
!!node->left + !!node->right
;
代码实现
int degree(BTreeNode<T>* node)const
int ld,rd,ret;
if(node == NULL)
return 0;
else
ld = degree(node->l_pointer);
rd = degree(node->r_pointer);
ret = !!node->l_pointer + !!node->r_pointer;
if(ret<ld)
ret = ld;
if(ret < rd)
ret = rd;
return ret;
二叉树的层次遍历
二叉树的遍历是指从根节点出发,按照某种次序依次访问二叉树中的所有结点,使得每个结点有且只有一次被访问,提供一组遍历相关的函数,按层次访问二叉树中的数据元素
算法设计
在二叉树中加入一个队列成员BQueue,该队列用来层次遍历使用
思想:
begin()->将根结点压入队列中
current()->访问队头元素指向的数据元素
next()->队头元素弹出,将队头元素的孩子压入队列中
end()->判断队列是都为空
bool begin()
bool ret = (root()!=NULL);
if(ret)
BQueue.clear();
BQueue.add(root());
return ret;
bool next()
bool ret = (BQueue.length()>0);
if(ret)
BTreeNode<T>* node = BQueue.front();
BQueue.remove();
if(node->l_pointer!=NULL)
BQueue.add(node->l_pointer);
if(node->r_pointer!=NULL)
BQueue.add(node->r_pointer);
return ret;
bool end()
return (BQueue.length()==0);
T current()
if(!end())
return BQueue.front()->value;
else
THROW_EXCEPTION(InvalidParamterException,"no value to read");
二叉树的其他遍历方式
先序遍历
1.访问根结点中的数据元素
2.先序遍历左子树
3.先序遍历右子树
中序遍历
1.中序遍历左子树
2.访问根结点中的数据元素
3.中序遍历右子树
后序遍历
1.中序遍历左子树
2.中序遍历右子树
3.访问根结点中的数据元素
接口设计
SharedPointer<Array<T>> traversal(BTTraversal order)
1.根据参数order选择执行遍历算法(先序,中序,后序)
2.返回值为堆中的数组对象(生命期由智能指针管理)
3.数组元素的次序反映遍历的先后次序
代码
BTree.h
template <typename T>
class BTree : public Tree<T>
private:
void PreOrderTraversal(BTreeNode<T>* node,LinkQueue<BTreeNode<T>*>& q)
if(node!=NULL)
q.add(node);
PreOrderTraversal(node->l_pointer,q);
PreOrderTraversal(node->r_pointer,q);
void InOrderTraversal(BTreeNode<T>* node,LinkQueue<BTreeNode<T>*>& q)
if(node!=NULL)
PreOrderTraversal(node->l_pointer,q);
q.add(node);
PreOrderTraversal(node->r_pointer,q);
void PostOrderTraversal(BTreeNode<T>* node,LinkQueue<BTreeNode<T>*>& q)
if(node!=NULL)
PreOrderTraversal(node->l_pointer,q);
PreOrderTraversal(node->r_pointer,q);
q.add(node);
public:
SharedPointer< Aarry <T> > traversal(BTTraversal order)
DynamicArray<T> *ret = NULL;
LinkQueue<BTreeNode<T>*> queue;
switch(order)
case PreOrder:
PreOrderTraversal(root(),queue);
break;
case InOrder:
InOrderTraversal(root(),queue);
break;
case PostOrder:
PostOrderTraversal(root(),queue);
break;
default:
THROW_EXCEPTION(InvalidParamterException,"Invaild para");
break;
cout<<"the queue's length is"<<queue.length()<<endl;
ret = new DynamicArray<T> (queue.length());
if(ret!=NULL)
for(int i =0;i<ret->length();i++,queue.remove())
ret->set(i,queue.front()->value);
;
else
THROW_EXCEPTION(NoEnougMemoryException,"no EnoungMemory......");
return ret;
main.c
#include <BTree.h>
int main()
BTree<int> bt;
BTreeNode<int>* n = NULL;
bt.insert(1,NULL);
n = bt.find(1);
bt.insert(2,n);
bt.insert(3,n);
n = bt.find(2);
bt.insert(4,n);
bt.insert(5,n);
n = bt.find(4);
bt.insert(8,n);
bt.insert(9,n);
n = bt.find(5);
bt.insert(10,n);
n=bt.find(3);
bt.insert(6,n);
bt.insert(7,n);
SharedPointer < Aarry <int> > sp = bt.traversal(PreOrder);
for(int i =0;i<(*sp).length();i++)
cout<<(*sp)[i]<<" ";
cout<<endl;
SharedPointer < Aarry <int> > sp1 = bt.traversal(InOrder);
for(int i =0;i<(*sp1).length();i++)
cout<<(*sp1)[i]<<" ";
cout<<endl;
SharedPointer < Aarry <int> > sp2 = bt.traversal(PostOrder);
for(int i =0;i<(*sp2).length();i++)
cout<<(*sp2)[i]<<" ";
return 0;
结果:
以上是关于二叉树的操作的主要内容,如果未能解决你的问题,请参考以下文章