二叉树的构造及常用方法
来源:互联网 发布:宜宾市行知中学周圣川 编辑:程序博客网 时间:2024/06/06 02:11
二叉树
定义:二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
特点:二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2^(i-1)个结点;深度为k的二叉树至多有2^k-1个结点;对任何一棵二叉树,如果其终端结点(即叶子节点)数为n0,度为2的结点数为n2,则n0=n2+1。
满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,即节点总数为2^k-1
完全二叉树:若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边
template<class T> //创建节点
struct BinaryTreeNode
{
public:
BinaryTreeNode(const T& value)
:_value(value)
,_pLeft(NULL)
,_pRight(NULL)
{}
T _value;
BinaryTreeNode<T>* _pLeft;
BinaryTreeNode<T>* _pRight;
};
template<class T> // 创建二叉树、二叉树的基本函数
class BinaryTree
{
public:
typedef BinaryTreeNode<T> Node;
BinaryTree() //构造函数
:_pRoot(NULL)
{}
BinaryTree(const T array[],size_t size,const T& invalid)
{
size_t index=0;
_CreateBinaryTree(_pRoot,array,size,index,invalid);
}
BinaryTree(const BinaryTree<T>& bt) //拷贝构造函数
{
cout<<endl<<"CopyBinaryTree"<<endl;
_pRoot=_CopyBinaryTree(bt._pRoot);
}
BinaryTree& operator=(const BinaryTree<T>& bt) //赋值运算符重载
{
if(this!=&bt)
{
_DestroyBinaryTree(_pRoot);
_pRoot=_CopyBinaryTree(bt._pRoot);
}
return *this;
}
~BinaryTree() //析构函数
{
_DestroyBinaryTree(_pRoot);
}
void _CreateBinaryTree(Node* &pRoot,const T array[],size_t size,size_t & index,const T& invalid) //构造二叉树
{
if(index<size && array[index]!=invalid) // 得到的字符为无效值时,不处理
{
pRoot=new Node(array[index]);
_CreateBinaryTree(pRoot->_pLeft,array,size,++index,invalid);
_CreateBinaryTree(pRoot->_pRight,array,size,++index,invalid);
}
}
Node* _CopyBinaryTree(Node* pRoot) //拷贝二叉树
{
Node* pNewNode=NULL;
if(pRoot)
{
pNewNode=new Node(pRoot->_value);
pNewNode->_pLeft=_CopyBinaryTree(pRoot->_pLeft);
pNewNode->_pRight=_CopyBinaryTree(pRoot->_pRight);
}
return pNewNode; //返回根节点
}
void _DestroyBinaryTree(Node*& pRoot) //销毁二叉树
{
if(pRoot)
{
_DestroyBinaryTree(pRoot->_pLeft);
_DestroyBinaryTree(pRoot->_pRight); //先销毁左右子树
delete pRoot; //再销毁根节点
pRoot=NULL; //根节点置空
}
}
void PerOrder()
{
cout<<"PerOrder:";
_PerOrder(_pRoot);
cout<<endl;
}
private:
void _PerOrder(Node* pRoot)
{
if(pRoot)
{
cout<<pRoot->_value<<" "; //访问根节点
_PerOrder(pRoot->_pLeft); //再左子树
_PerOrder(pRoot->_pRight); //再右子树
}
}
void _InOrder(Node* pRoot)
{
if(pRoot)
{
_InOrder(pRoot->_pLeft);
cout<<pRoot->_value<<" ";
_InOrder(pRoot->_pRight);
}
}
//后序遍历
void _PostOrder(Node* pRoot)
{
if(pRoot)
{
_PostOrder(pRoot->_pLeft);
_PostOrder(pRoot->_pRight);
cout<<pRoot->_value<<" ";
}
}
Node* Find(const T& value) //包装Find方法
{
return _Find(_pRoot,value);
}
private:
Node* _Find(Node* pRoot,const T& value)
{
if(NULL==pRoot) //树空---NULL
return NULL;
if(pRoot->_value == value) //根节点就是要找的节点
Node* pCur=NULL;
if(pCur=_Find(pRoot->_pLeft,value)) //左子树中找
return pCur;
if(_Find(pRoot->_pRight,value)) //右子树中找
}
Node* Find(const T& value)
{
return _Find(_pRoot,value);
}
private:
Node* _Find(Node* pRoot,const T& value)
{
if(NULL==pRoot) //树空
return NULL;
if(pRoot->_value == value)
return pRoot;
Node* pCur=NULL;
if(pCur=_Find(pRoot->_pLeft,value))
return pCur;
if(_Find(pRoot->_pRight,value))
return pCur;
}
{
if(NULL==pRoot)
return 0;
if(NULL==pRoot->_pLeft && NULL==pRoot->_pRight)
return 1;
size_t LeftHeight=_Height(pRoot->_pLeft);
size_t RightHeight=_Height(pRoot->_pRight);
return (LeftHeight>RightHeight)? LeftHeight+1:RightHeight+1;
}
{
if(NULL==pRoot)
return 0;
if(NULL==pRoot->_pLeft && NULL==pRoot->_pRight)
return 1;
size_t LeftLeefCount=_GetLeefCount(pRoot->_pLeft);
size_t RightLeefCount=_GetLeefCount(pRoot->_pRight);
return LeftLeefCount+RightLeefCount;
}
{
if(NULL==pRoot || k<1)
return 0;
if(1==k)
return 1;
return _GetKLevelCount(pRoot->_pLeft,k-1)+_GetKLevelCount(pRoot->_pRight,k-1);
}
{
if(pRoot)
{
std::swap(pRoot->_pLeft,pRoot->_pRight); //交换左右子树
_BinaryMirror(pRoot->_pLeft); //对左子树进行镜像处理
_BinaryMirror(pRoot->_pRight); //对右子树进行镜像处理
}
}
{
cout<<"PerOrder_Nor:"<<" ";
if(NULL==_pRoot)
return;
stack<Node*> s;
s.push(_pRoot);
while(!s.empty())
{
Node* pTop=s.top();
cout<<pTop->_value<<" ";
s.pop();
if(pTop->_pRight)
s.push(pTop->_pRight);
if(pTop->_pLeft)
s.push(pTop->_pLeft);
}
cout<<endl;
}
void InOrder_Nor()
{
cout<<"InOrder_Nor:"<<" ";
if(NULL == _pRoot)
return;
stack<Node*> s;
Node* pCur=_pRoot;
while(pCur || !s.empty())
{
while(pCur)
{
s.push(pCur);
pCur=pCur->_pLeft;
}
pCur=s.top();
cout<<pCur->_value<<" ";
s.pop();
pCur=pCur->_pRight;
}
cout<<endl;
}
void PostOrder_Nor()
{
cout<<"PostOrder_Nor:"<<" ";
if(NULL == _pRoot)
return;
stack<Node*> s;
Node* pCur=_pRoot;
Node* prev=NULL;
while(pCur || !s.empty())
{
while(pCur)
{
s.push(pCur);
pCur=pCur->_pLeft;
}
Node* pTop=s.top();
if(NULL == pTop->_pRight || pTop->_pRight==prev)
{
cout<<pTop->_value<<" ";
prev=pTop;
s.pop();
}
else
pCur=pTop->_pRight;
}
}
{
if(pRoot)
{
_InOrder(pRoot->_pLeft);
cout<<pRoot->_value<<" ";
_InOrder(pRoot->_pRight);
}
}
- 二叉树的构造及常用方法
- 二叉树的基本构造及遍历方法
- 二叉树的构造方法
- 二叉树的构造及遍历
- 二叉搜索树的一种构造方法
- 铣扁机的常用加工方法及构造原理
- 平衡二叉树 构造方法
- 二叉树构造方法比较
- 平衡二叉树 构造方法
- 平衡二叉树构造方法
- 平衡二叉树 构造方法
- 平衡二叉树 构造方法
- 二叉树的构造
- 二叉树的构造
- 二叉树的构造
- 二叉树的构造
- 二叉树的构造
- 二叉树的构造
- 内存管理(四)tcmalloc2 内存释放及源码剖析
- 弦图判断
- iOS——消息传递
- Git教程
- 安装Ubuntu12.0.4LTS/14.045 LTS 编译Android6.0/7.0环境
- 二叉树的构造及常用方法
- LeetCode算法题目:Search a 2D Matrix
- 机器学习-->深度学习-->人工神经网络
- 微信小程序带字母滑动的listview----项目实战
- 树、森林及二叉树的相互转换
- [设计模式]装饰者模式(Decorator)
- Microsoft Google Facebook等公司保证代码质量的方法
- 补作业 第五次实验 项目4
- 链式存储的字符串的基本操作(学习历程)