二叉树节点结构
template<class T>
struct BinaryTreeNode
{
BinaryTreeNode(const T& data)
:_data(data)
,_pLeft(NULL)
,_pRight(NULL)
{}
T _data;
BinaryTreeNode<T>* _pLeft;
BinaryTreeNode<T>* _pRight;
};
二叉树的构造
template<class T>
class BinaryTree
{
typedef BinaryTreeNode<T> Node;
public:
//构造函数
BinaryTree()
:_pRoot(NULL)
{}
BinaryTree(const T array[], size_t size, const T& invalid)
{
size_t index = 0;
_CreateTree(_pRoot, array, size, index, invalid);
}
//拷贝构造函数
BinaryTree(const BinaryTree<T>& t)
{
_pRoot = _CopyBinaryTree(t._pRoot );
}
//赋值运算符重载
BinaryTree<T>& operator=(const BinaryTree<T>& t)
{
//先销毁当前对象,再拷贝
_DestroyTree(t._pRoot );
_CopyBinaryTree(t._pRoot );
}
~BinaryTree()
{
_DestroyTree(_pRoot);
}
private:
void _CreateTree(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]);
_CreateTree(pRoot->_pLeft ,array,size,++index,invalid);
_CreateTree(pRoot->_pRight ,array,size,++index,invalid);
}
}
Node* _CopyBinaryTree(Node* pRoot)
{
if(NULL != pRoot)
{
Node* pNew = new Node(pRoot->_data);
pNew->_pLeft = _CopyBinaryTree(pRoot->_pLeft );
pNew->_pRight = _CopyBinaryTree(pRoot->_pRight );
return pNew;
}
return NULL;
}
void _DestroyTree(Node* pRoot)
{
if(pRoot)
{
_DestroyTree(pRoot->_pLeft );
_DestroyTree(pRoot->_pRight );
delete pRoot;
pRoot = NULL;
}
}
private:
BinaryTreeNode<T>* _pRoot;
};
二叉树遍历——递归
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;
}
private:
void _PreOrder(Node* pRoot)
{
if(pRoot)
{
cout<<pRoot->_data <<" ";
_PreOrder(pRoot->_pLeft );
_PreOrder(pRoot->_pRight );
}
}
void _InOrder(Node* pRoot)
{
if(pRoot)
{
_InOrder(pRoot->_pLeft );
cout<<pRoot->_data <<" ";
_InOrder(pRoot->_pRight );
}
}
void _PostOrder(Node* pRoot)
{
if(pRoot)
{
_PostOrder(pRoot->_pLeft );
_PostOrder(pRoot->_pRight );
cout<<pRoot->_data <<" ";
}
}
二叉树遍历——非递归
//先序遍历
void _PreOrder_Nor(Node* pRoot)
{
if(pRoot)
{
stack<Node*> s;
Node* pCur = pRoot;
s.push(pCur);
while(!s.empty())
{
pCur = s.top();
cout<<pCur->_data <<" ";
s.pop();
if(pCur->_pRight )
s.push(pCur->_pRight );
if(pCur->_pLeft )
s.push(pCur->_pLeft );
}
}
}
//中序遍历
void _InOrder_Nor(Node* pRoot)
{
stack<Node*> s;
Node* pCur = pRoot;
while(pCur || !s.empty())
{
while(pCur)
{
s.push(pCur);
pCur = pCur->_pLeft ;
}
pCur = s.top();
cout<<pCur->_data <<" ";
s.pop();
pCur = pCur->_pRight ;
//while(NULL == pCur->_pRight )
//{
// pCur = s.top();
// cout<<pCur->_data <<" ";
// s.pop();
//}
//pCur = pCur->_pRight ;
}
}
//后序遍历
void _PostOrder_Nor(Node* pRoot)
{
stack<Node*> s;
Node* pCur = pRoot;//指向根节点
Node* pPre = NULL;//指向已经访问过的节点
Node* pTop = NULL;//指向栈顶节点
while(pCur || !s.empty())
{
while(pCur)
{
s.push(pCur);
pCur = pCur->_pLeft ;
}
pTop = s.top();
//当节点右子树为空或当前右节点已经访问过,则对该节点进行访问
if(pTop->_pRight == NULL || pPre == pTop->_pRight )
{
cout<<pTop->_data <<" ";
pPre = pTop;
s.pop();
}
//转换为子问题
else
pCur = pTop->_pRight ;
//注意是pCur是指向栈顶节点的右节点
}
}
二叉树层序遍历
// 层序遍历
void LevelOrder()
{
cout<<" LevelOrder()"<<endl;
queue<Node*> q;//申请一个保存二叉树节点的队列
Node* pCur = NULL;
if(NULL != _pRoot)
{
q.push (_pRoot);
while(!q.empty ())
{
pCur = q.front ();
cout<<pCur->_data <<" ";
if(pCur->_pLeft )
q.push (pCur->_pLeft );
if(pCur->_pRight )
q.push (pCur->_pRight );
q.pop ();
}
}
cout<<endl;
}
二叉树面试题
求镜像二叉树
public:
//求某一二叉树的镜像——递归
void GetBinaryMirror()
{
_GetBinaryMirror(_pRoot);
}
//求某一二叉树的镜像——非递归
void GetBinaryMirror_Nor()
{
_GetBinaryMirror_Nor(_pRoot);
}
void _GetBinaryMirror(Node* pRoot)
{
if(pRoot)
{
std::swap (pRoot->_pLeft ,pRoot->_pRight );
_GetBinaryMirror(pRoot->_pLeft );
_GetBinaryMirror(pRoot->_pRight );
}
}
private:
void _GetBinaryMirror_Nor(Node* pRoot)
{
queue<Node*> q;
q.push(pRoot);
while(!q.empty())
{
Node* pCur = q.front();
std::swap (pCur->_pLeft ,pCur->_pRight );
if(pCur->_pLeft )
q.push(pCur->_pLeft );
if(pCur->_pRight )
q.push(pCur->_pRight );
q.pop();
}
}
判断一棵树是不是完全二叉树
//判断一颗树是否为完全二叉树
bool IsCompleteBinaryTree()
{
bool flag = true;//判断一棵子树是否为一棵二叉树的标记
queue<Node*> q;//运用队列进行层序遍历
q.push(_pRoot);
while(!q.empty())
{
Node* pCur = q.front();
q.pop();
//如果队首元素的左子树为空将标记置为false如果层序遍历后面的节点还有子树说明不是
if(NULL == pCur->_pLeft )
flag = false;
else
{
//如果falg为假,说明之前已经有节点的孩子为空,又因当前节点的左孩子不为空,说明不是
if(flag == false)
return false;
q.push(pCur->_pLeft );
}
//如果队首元素的右树为空,将标记置为false如果层序遍历后面的节点还有子树,说明不是
if(NULL == pCur->_pRight )
flag = false;
else
{
//如果flag为假说明之前已经有节点的孩子为空,又因当前节点的右孩子不为空说明不是
if(flag == false)
return false;
q.push(pCur->_pRight );
}
}
return true;
}
public:
//找双亲节点
Node* GetParent(T& value)
{
Node* x = Find(value);
return _GetParent(_pRoot,x);
}
private:
Node* _GetParent(Node* pRoot,Node* x)
{
if(pRoot == NULL||x == NULL||pRoot == x)
return NULL;
if(x == pRoot->_pLeft || x == pRoot->_pRight )
return pRoot;
Node* pLeft = _GetParent(pRoot->_pLeft ,x);
Node* pRight = _GetParent(pRoot->_pRight ,x);
}
public:
//判断某节点是否存在
Node* Find(const T& value)
{
return _Find(_pRoot,value);
}
private:
Node* _Find(Node* pRoot,const T& value)
{
if(NULL == pRoot)
return NULL;
if(pRoot->_data == value)
return pRoot;
Node* pCur = _Find(pRoot->_pLeft ,value);
if(pCur)
return pCur;
return _Find(pRoot->_pRight ,value);
}
//获得某节点的左孩子
Node* GetLeftChild(Node* pCur)
{
return (NULL == pCur)?NULL:pCur->_pLeft ;
}
//获得某节点的右孩子
Node* GetRightChild(Node* pCur)
{
return (NULL == pCur)?NULL:pCur->_pRight ;
}
//计算二叉树的高度
size_t Height()
{
return _Height(_pRoot);
}
size_t _Height(Node* pRoot)
{
if(NULL == pRoot)
return 0;
if(NULL == pRoot->_pLeft && NULL == pRoot->_pRight )
return 1;
size_t hLeft = _Height(pRoot->_pLeft );
size_t hRight = _Height(pRoot->_pRight );
return hLeft>hRight?hLeft+1:hRight+1;
}
//计算叶子节点的个数
size_t GetLeafNode()
{
return _GetLeafNode(_pRoot);
}
size_t _GetLeafNode(Node* pRoot)
{
if(NULL == pRoot)
return 0;
if(NULL == pRoot->_pLeft && NULL == pRoot->_pRight )
return 1;
return _GetLeafNode(pRoot->_pLeft )+_GetLeafNode(pRoot->_pRight );
}
//计算第K层的节点数
size_t GetKLevelNode(size_t k)
{
return _GetKLevelNode(_pRoot, k);
}
size_t _GetKLevelNode(Node* pRoot,size_t k)
{
if(NULL == pRoot && k<1 && k>_Height(pRoot))
return 0;
if(k == 1)
return 1;
size_t kLeft = _GetKLevelNode(pRoot->_pLeft ,k-1);
size_t kRight = _GetKLevelNode(pRoot->_pRight ,k-1);
return kLeft + kRight;
}