1.构造二叉树
#include<iostream>
#include<queue>
#include<stack>
#include<assert.h>
using namespace std;
template<class T>
struct BinaryTreeNode
{
T _value;
BinaryTreeNode<T>* _pLeft;//左孩子
BinaryTreeNode<T>* _pRight;//右孩子
BinaryTreeNode(const T& value)
:_value(value)
,_pLeft(NULL)
,_pRight(NULL)
{}
};
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)//拷贝构造函数
{
_pRoot=_CopyBinaryTree(bt._pRoot);
}
~BinaryTree()
{
_DestroyBinaryTree(_pRoot);
}
BinaryTree<T>& operator=(const BinaryTree<T>& bt)
{
if(this!=&bt)
{
__DestroyBinaryTree(_pRoot);
_pRoot=_CopyBinaryTree(bt._pRoot);
}
return *this;
}
private:
void _CreateBinaryTree(Node* &pRoot,const T array[],size_t size,size_t& index,const T& invalid)
{
if(index<size&&invalid!=array[index])
{
pRoot=new Node(array[index]);
_CreateBinaryTree(pRoot->_pLeft,array,size,++index,invalid);//创建左子树
_CreateBinaryTree(pRoot->_pRight,array,size,++index,invalid);//创建右子树
}
}
Node* _CopyBinaryTree(Node* pRoot)//拷贝
{
Node* pNewRoot=NULL;
if(pRoot)
{
//拷贝根节点
pNewRoot=new Node(pRoot->_value);
//拷贝左子树
pNewRoot->_pLeft=_CopyBinaryTree(pRoot->_pLeft);
//拷贝右子树
pNewRoot->_pRight=_CopyBinaryTree(pRoot->_pRight);
}
return pNewRoot;
}
void _DestroyBinaryTree(Node* &pRoot)
{
if(pRoot)
{
_DestroyBinaryTree(pRoot->_pLeft);
_DestroyBinaryTree(pRoot->_pRight);
delete pRoot;
pRoot=NULL;
}
}
private:
Node* _pRoot;
};
2.二叉树的遍历—递归形式
public:
void PreOrder()//前序遍历(递归)--接口
{
cout<<"PreOrder:"<<endl;
_PreOrder(_pRoot);
cout<<endl;
}
void InOrder()//中序遍历(递归)---接口
{
cout<<"InOrder:"<<endl;
_InOrder(_pRoot);
cout<<endl;
}
void PostOrder()//后序遍历(递归)---接口
{
cout<<"PostOrder:"<<endl;
_PostOrder(_pRoot);
cout<<endl;
}
void LevelOrder()//层序遍历
{
if(NULL==_pRoot)
return;
queue<Node*> q;
q.push(_pRoot);
cout<<"LevelOrder:"<<endl;
while(!q.empty())//队列不为空
{
Node* pCur=q.front();//取队头元素
if(pCur->_pLeft)
q.push(pCur->_pLeft);//取左子树
if(pCur->_pRight)
q.push(pCur->_pRight);//取右子树
cout<<pCur->_value<<" ";//访问队头
q.pop();//出队列
}
cout<<endl;
}
private:
void _PreOrder(Node* pRoot)//前序遍历(递归)
{
if(pRoot)
{
cout<<pRoot->_value<<" ";
_PreOrder(pRoot->_pLeft);
_PreOrder(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<<" ";
}
}
3.二叉树的遍历—-非递归形式
public:
void _PreOrder_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 _PreOrder_Nor()//前序遍历(非递归)---方法二:左右结点都存在时,将右结点入栈,直接访问左结点
{
if(NULL==_pRoot)
return;
stack<Node*> s;
s.push(_pRoot);
while(!s.empty())
{
Node* pCur=s.top();
s.pop();
while(pCur)
{
cout<<pCur->_value<<" ";
if(pCur->_pRight)
s.push(pCur->_pRight);
pCur=pCur->_pLeft;
}
}
cout<<endl;
}
void _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();
while(NULL==pCur->_pRight && !s.empty())//右子树不存在时
{
pCur=s.top();
cout<<pCur->_value<<" ";
s.pop();
}
pCur=pCur->_pRight;
}
cout<<endl;
}
void _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||prev==pTop->_pRight)//右子树存在时,可能会被访问两次,造成死循环,所以要判断是否已经访问过
{
cout<<pTop->_value<<" ";
prev=pTop;
s.pop();
}
else
pCur=pTop->_pRight;
}
cout<<endl;
}
4.找二叉树中是否有某个节点
public:
Node* Find(const T& value)//找二叉树中某个结点
{
Node* pCur=NULL;
pCur=_Find(_pRoot,value);
cout<<pCur->_value<<endl;
return pCur;
}
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;
return _Find(pRoot->_pRight,value);
}
4.获取双亲节点
public:
Node* Parent(Node* pCur)//寻找双亲结点
{
Node* result=NULL;
result=_Parent(_pRoot,pCur);
cout<<"Parent:"<<endl;
cout<<result->_value<<endl;
return result;
}
private:
Node* _Parent(Node* pRoot,Node* pCur)//获取双亲,pRoot为根节点
{
assert(pCur);
if(pRoot==NULL||pCur==pRoot)
return NULL;
if((pCur==pRoot->_pLeft)||(pCur==pRoot->_pRight))
return pRoot;
Node* ret=NULL;
if(ret=_Parent(pRoot->_pLeft,pCur))
return ret;
else
return _Parent(pRoot->_pRight,pCur);
}
5.获取左孩子节点
public:
Node* LeftChild(Node* pCur)//寻找左孩子结点
{
Node* result=NULL;
result=_LeftChild(_pRoot,pCur);
cout<<"LeftChild:"<<endl;
cout<<result->_value<<endl;
return result;
}
private:
Node* _LeftChild(Node* pRoot,Node* pCur)
{
assert(pCur);
if(pRoot!=NULL && pCur->_pLeft!=NULL)
return pCur->_pLeft;
Node* ret=NULL;
if(ret=_LeftChild(pRoot->_pLeft,pCur))
return ret;
else
return _LeftChild(pRoot->_pRight,pCur);
}
6.获取右孩子节点
public:
Node* RightChild(Node* pCur)//寻找右孩子结点
{
Node* result=NULL;
result=_RightChild(_pRoot,pCur);
cout<<"RightChild:"<<endl;
cout<<result->_value<<endl;
return result;
}
private:
Node* _RightChild(Node* pRoot,Node* pCur)
{
assert(pCur);
if(pRoot!=NULL && pCur->_pRight!=NULL)
return pCur->_pRight;
Node* ret=NULL;
if(ret=_RightChild(pRoot->_pLeft,pCur))
return ret;
else
return _RightChild(pRoot->_pRight,pCur);
}
7.计算二叉树的深度
public:
size_t Height()//计算二叉树的深度
{
size_t depth=0;
depth=_Height(_pRoot);
cout<<"Height:"<<depth<<endl;
return depth;
}
private:
size_t _Height(Node* pRoot)//计算二叉树的深度
{
int hl=0;
int hr=0;
int max=0;
if(pRoot!=NULL)
{
hl=_Height(pRoot->_pLeft);
hr=_Height(pRoot->_pRight);
max=hl>hr?hl:hr;
return max+1;
}
else
return 0;
}
8.计算二叉树的叶子节点个数
public:
size_t GetLeefCount()//计算叶子结点个数
{
size_t count=0;
count=_GetLeefCount(_pRoot);
cout<<"leefcount: "<<count<<endl;
return count;
}
privte:
size_t _GetLeefCount(Node* pRoot)//计算叶子结点个数
{
if(pRoot==NULL)
return 0;
if(NULL==pRoot->_pLeft && NULL==pRoot->_pRight)
return 1;
return _GetLeefCount(pRoot->_pLeft)+_GetLeefCount(pRoot->_pRight);
}
9.计算二叉树第k层的节点个数
public:
size_t GetKLevelCount(size_t k)//计算二叉树第k层结点数
{
size_t count=0;
count=_GetKLevelCount(_pRoot, k);
cout<<"KLevelCount: "<<count<<endl;
return count;
}
private:
size_t _GetKLevelCount(Node* pRoot,size_t k)//计算二叉树的第K层节点数
{
if(pRoot==NULL||k<1)
return 0;
if(k==1)
return 1;
return _GetKLevelCount(pRoot->_pLeft,k-1)+_GetKLevelCount(pRoot->_pRight,k-1);
}
10.求二叉树的镜像树—-递归形式
public:
void BinaryMirror()//求镜像树(递归)
{
_BinaryMirror(_pRoot);
}
private:
void _BinaryMirror(Node* pRoot)//镜像树(递归)
{
if(pRoot)
{
std::swap(pRoot->_pLeft,pRoot->_pRight);
_BinaryMirror(pRoot->_pLeft);
_BinaryMirror(pRoot->_pRight);
}
}
11.求二叉树的镜像树—-非递归形式
public:
void BinaryMirror_Nor()//求镜像树(非递归)
{
if(NULL==_pRoot)
return;
queue<Node*> q;
q.push(_pRoot);
while(!q.empty())
{
Node* pCur=q.front();
if(pCur->_pLeft)
q.push(pCur->_pLeft);
if(pCur->_pRight)
q.push(pCur->_pRight);
std::swap(pCur->_pLeft,pCur->_pRight);
q.pop();
}
}
12.判断是否为完全二叉树
public:
bool IsCompleteBinaryTree()//判断是否为完全二叉树?
{
if(NULL==_pRoot)
return true;
bool flag=false;
queue<Node*> q;
q.push(_pRoot);
while(!q.empty())
{
Node* pCur=q.front();
if(flag)//判断到此处时,说明pCur已经指向一棵右子树
{
if(pCur->_pLeft||pCur->_pRight)
return false;
}
if(pCur->_pLeft && pCur->_pRight)
{
q.push(pCur->_pLeft);
q.push(pCur->_pRight);
}
else if(pCur->_pLeft)
{
q.push(pCur->_pLeft);
flag=true;
}
else if(pCur->_pRight)
return false;
else
flag=true;
q.pop();
}
return true;
}
13.根据前序遍历和中序遍历的结果重建二叉树
public:
Node* ReBuild_PreIn(T Pre[],int start_Pre,int end_Pre,T In[],int start_In,int end_In)//根据前序遍历和中序遍历的结果重建二叉树
{
if((end_Pre-start_Pre)!=(end_In-start_In)||start_Pre>end_Pre)
return NULL;
Node* pCur=new Node(sizeof(Pre));
pCur->_value=Pre[start_Pre];
pCur->_pLeft=NULL;
pCur->_pRight=NULL;
if(start_Pre==end_Pre)
return pCur;
int index=0;
int length=0;
for(index=start_In;index<=end_In;index++)
{
if(In[index]==Pre[start_Pre])
break;
}
if(index>end_In)
return NULL;
if (index > start_In)
{
length = index-start_In;
pCur->_pLeft= ReBuild_PreIn(Pre,start_Pre+1,start_Pre+1+length-1,In,start_In,start_In+length-1);
}
//有右子树,递归调用构建右子树
if (index < end_In)
{
length = end_In - index;
pCur->_pRight= ReBuild_PreIn(Pre,end_Pre-length+1,end_Pre,In,end_In-length+1,end_In);
}
return pCur;
}
14.求两个节点最近的公共祖先
public:
void CommonAncestor(Node* node1,Node* node2)
{
//bool flag=false;
cout<<(_CommonAncestor(_pRoot,node1,node2))->_value<<endl;
}
private:
bool _GetPath(Node* pRoot,Node* pCur,stack<Node*>& s)//在根为pRoot的树中查找节点pCur的路径
{
if (NULL == pRoot || NULL == pCur)//树为空
return false;
s.push(pRoot); //将当前节点入栈
if (pCur->_value == pRoot->_value) //找到路径
{
return true;
}
if (_GetPath(pRoot->_pLeft,pCur,s))//在左子树中找路径
{
return true;
}
if (_GetPath(pRoot->_pRight,pCur,s))//在右子树中找路径
{
return true;
}
s.pop();
return false;
}
Node* _CommonAncestor(Node*& pRoot,Node* n1,Node* n2)//求两个节点的最近公共祖先(时间复杂度:O(N))
{
//树为空
if (NULL == pRoot)
{
return NULL;
}
stack<Node*> s1;
stack<Node*> s2;
//用栈s1和s2分别保存节点n1和节点n2的路径
_GetPath(pRoot,n1,s1);
_GetPath(pRoot,n2,s2);
//将多余的路径删除
while (s1.size() > s2.size())
{
s1.pop();
}
while(s1.size() < s2.size())
{
s2.pop();
}
//找s1与s2中不同的节点
while(s1.top() != s2.top())
{
s1.pop();
s2.pop();
}
return s1.top();
}
15.测试代码:
void Test()
{
char* pStr="124###35##6";
char* pStrs="124##5##3";
char* PreOrder="124356";
char* InOrder="421536";
BinaryTree<char> bt1(pStr,strlen(pStr),'#');
BinaryTree<char> bts(pStrs,strlen(pStrs),'#');
//bt1.ReBuild_PreIn(PreOrder,0,5,InOrder,0,5);
bt1.CommonAncestor(bt1.Find('5'),bt1.Find('6'));
//bt1.PreOrder();
//bt1.InOrder();
//bt1.PostOrder();
//bt1.LevelOrder();
//bt1.Find('5');
//bt1.Parent(bt1.Find('5'));
//bt1.LeftChild(bt1.Find('1'));
//bt1.RightChild(bt1.Find('1'));
//bt1.Height();
//bt1.GetLeefCount();
//bt1.GetKLevelCount(4);
//bt1.BinaryMirror_Nor();
//bt1.BinaryMirror();
//bt1._PreOrder_Nor();
//bt1._InOrder_Nor();
//bt1._PostOrder_Nor();
//cout<<bts.IsCompleteBinaryTree()<<endl;
/*cout<<endl;
BinaryTree<char> bt2(bt1);
bt2.PreOrder();
bt2.InOrder();
bt2.PostOrder();
cout<<endl;
BinaryTree<char> bt3=bt1;
bt3.PreOrder();
bt3.InOrder();
bt3.PostOrder();*/
}
int main()
{
Test();
return 0;
}