二叉树 常见操作

来源:互联网 发布:手机淘宝怎么看收藏量 编辑:程序博客网 时间:2024/05/01 15:34

template<class _T>
struct _TNode
{
 _T data;
 _TNode* pLeft;
 _TNode* pRight;
 _TNode* pParent;
 _TNode()
 {
  pLeft = pRight = pParent = NULL;
 }
};

template<typename _T>
class CBinaryTree
{
public:
 CBinaryTree()
 {
  m_pRoot = NULL;
 }
 ~CBinaryTree()
 {
  Clear();
 }
 void CreateTree(const _T& t);
 void PreOrder() const;
 void InOrder() const;
 void PostOrder() const;
 void LevelOrder() const;

 void Layout() const;
 void Layout2() const;

 int Height() const;
private:
 void CreateTree(_TNode<_T>** ppNode,const _T& t);

 CBinaryTree(const CBinaryTree& tree);
 CBinaryTree& operator = (const CBinaryTree& tree);

 void Clear();
 void Clear(_TNode<_T>* pNode);

 int Height(const _TNode<_T>* pNode) const;

 void inline Visit(const _TNode<_T>* PNode) const;

 // 递归
 void PreOrder(const _TNode<_T>* pNode) const;
 void InOrder(const _TNode<_T>* pNode) const;
 void PostOrder(const _TNode<_T>* pNode) const; 

 //非递归
 void PreOrderNoRecursion(const _TNode<_T>* pNode) const;
 void InOrderNoRecursion(const _TNode<_T>* pNode) const;
 void PostOrderNoRecursion(const _TNode<_T>* pNode) const;
 void LevelOrderNoRecursion(const _TNode<_T>* pNode) const;

 _TNode<_T>* m_pRoot;
};

template<typename _T>
void CBinaryTree<_T>::Visit(const _TNode<_T>* pNode) const
{
 if (pNode != NULL)
 {
  cout << pNode->data << endl;
 }
}

template<typename _T>
void CBinaryTree<_T>::Clear(_TNode<_T>* pNode)
{
 if (pNode != NULL)
 {
  _TNode<_T>* pLeft = pNode->pLeft;
  _TNode<_T>* pRight = pNode->pRight;

  delete pNode;
  Clear(pLeft);
  Clear(pRight);
 }
}

template<typename _T>
void CBinaryTree<_T>::Clear()
{
 stack<_TNode<_T>*,vector<_TNode<_T>*>> TStack;

 if (m_pRoot != NULL)
  TStack.push(m_pRoot);

 _TNode<_T>* pCur = TStack.top();
 while (!TStack.empty())
 {
  TStack.pop();
  if (pCur != NULL)
  {
   TStack.push(pCur->pRight);
   TStack.push(pCur->pLeft);

   delete pCur;
   pCur = NULL;
  }  
  if (!TStack.empty())
  {
   pCur = TStack.top();
  }
 }
}

template<typename _T>
void CBinaryTree<_T>::CreateTree(const _T& t)
{
 return CreateTree(&m_pRoot,t);
}

template<typename _T>
void CBinaryTree<_T>::CreateTree(_TNode<_T>** ppNode,const _T& t)
{
 if (ppNode == NULL)
 {
  cout << "Invalid Parameter" << endl;
 }

 if (*ppNode == NULL)
 {
  *ppNode = new _TNode<_T>;
  (*ppNode)->data = t;
 }
 else
 {
  if ((*ppNode)->data > t)
  {
   CreateTree(&(*ppNode)->pLeft,t);
  }
  else
  {
   CreateTree(&(*ppNode)->pRight,t);
  }
 }
}

template<typename _T>
void CBinaryTree<_T>::PreOrder() const
{
 PreOrderNoRecursion(m_pRoot);
 return PreOrder(m_pRoot);
}

template<typename _T>
void CBinaryTree<_T>::PreOrder(const _TNode<_T>* pNode) const
{
 if (pNode == NULL)
  return;

 Visit(pNode);
 PreOrder(pNode->pLeft);
 PreOrder(pNode->pRight);
}

template<typename _T>
void CBinaryTree<_T>::PreOrderNoRecursion(const _TNode<_T>* pNode) const
{
 stack<const _TNode<_T>*> TStack;

#if 0
 if (pNode != NULL)
 {
  const _TNode<_T>* pCur = pNode;
  while (pCur != NULL)
  {
   Visit(pCur);
   if (pCur->pRight != NULL)
   {
    TStack.push(pCur->pRight);
   }

   if (pCur->pLeft != NULL)
   {
    TStack.push(pCur->pLeft);
   }

   if (!TStack.empty())
   {
    pCur = TStack.top();
    TStack.pop();
   }
   else
   {
    pCur = NULL;
   }
  }
 }
#else
 const _TNode<_T>* pCur = pNode;
 while (!TStack.empty() || (pCur != NULL))
 {
  while (pCur != NULL)
  {
   Visit(pCur);
   TStack.push(pCur);
   pCur = pCur->pLeft;
  }
  if (!TStack.empty())
  {
   pCur = TStack.top();
   TStack.pop();
   pCur = pCur->pRight;
  }
 }
#endif
}

template<typename _T>
void CBinaryTree<_T>::InOrder() const
{
 InOrderNoRecursion(m_pRoot);
 return InOrder(m_pRoot);
}

template<typename _T>
void CBinaryTree<_T>::InOrder(const _TNode<_T>* pNode) const
{
 if (pNode == NULL)
  return;
 InOrder(pNode->pLeft);
 Visit(pNode);
 InOrder(pNode->pRight);
}

template<typename _T>
void CBinaryTree<_T>::InOrderNoRecursion(const _TNode<_T>* pNode) const
{
 const _TNode<_T>* pCur = NULL;
 stack<const _TNode<_T>*> TStack;

 pCur = pNode;
 while (!TStack.empty() || (pCur != NULL))
 {
  while (pCur != NULL)
  {
   TStack.push(pCur);
   pCur = pCur->pLeft;
  }

  if (!TStack.empty())
  {
   pCur = TStack.top();
   TStack.pop();
   Visit(pCur);
   pCur = pCur->pRight;
  }
 }
}

template<typename _T>
void CBinaryTree<_T>::PostOrder() const
{
 PostOrderNoRecursion(m_pRoot);
 return PostOrder(m_pRoot);
}

template<typename _T>
void CBinaryTree<_T>::PostOrder(const _TNode<_T>* pNode) const
{
 if (pNode == NULL)
  return;

 PostOrder(pNode->pLeft);
 PostOrder(pNode->pRight);
 Visit(pNode);
}

template<typename _T>
void CBinaryTree<_T>::PostOrderNoRecursion(const _TNode<_T>* pNode) const
{
 const _TNode<_T>* pCur = pNode;
 const _TNode<_T>* pPre = NULL;
 stack<const _TNode<_T>*> TStack;

 while (!TStack.empty() || (pCur != NULL))
 {
  if (pCur != NULL)
  {
   TStack.push(pCur);
   pCur = pCur->pLeft;
  }
  else
  {
   pCur = TStack.top();
   if ((pCur->pRight != NULL) && (pPre != pCur->pRight))
   {
    pCur = pCur->pRight;
   }
   else
   {
    pPre = pCur;
    Visit(pCur);
    TStack.pop();
    pCur = NULL;
   }
  }
 }
}

template<typename _T>
void CBinaryTree<_T>::LevelOrder() const
{
 return LevelOrderNoRecursion(m_pRoot);
}

template<typename _T>
void CBinaryTree<_T>::LevelOrderNoRecursion(const _TNode<_T>* pNode) const
{
 queue<const _TNode<_T>*> TQueue;
 const _TNode<_T>* pCur = pNode;

 while (pCur != NULL)
 {
  Visit(pCur);
  if (pCur->pLeft != NULL)
  {
   TQueue.push(pCur->pLeft);
  }
  if (pCur->pRight != NULL)
  {
   TQueue.push(pCur->pRight);
  }

  if (!TQueue.empty())
  {
   pCur = TQueue.front();
   TQueue.pop();
  }
  else
  {
   pCur = NULL;
  }
 }
}

template<typename _T>
void CBinaryTree<_T>::Layout() const
{
 stack<pair<const _TNode<_T>*,int>> TStack2;
 stack<const _TNode<_T>*> TStack;
 const _TNode<_T>* pCur = m_pRoot;
 int index = 0;

 while ( pCur != NULL || !TStack.empty())
 {
  while (pCur != NULL)
  {
   TStack.push(pCur);
   TStack2.push(make_pair(pCur,index));
   pCur = pCur->pLeft;
   index++;
  }
  if (!TStack.empty())
  {   
   pCur = TStack.top();

   pair<const _TNode<_T>*,int> node = TStack2.top();

   for (int i = 0; i < node.second; ++i)
   {
    cout << '/t' ;
   }
   cout << node.first->data << endl;

   TStack.pop();
   TStack2.pop();
   pCur = pCur->pRight;
   if (pCur == NULL)
    index--;
  }
 }
}

template<typename _T>
void CBinaryTree<_T>::Layout2() const
{
 queue<const _TNode<_T>*> TQueue;
 queue<pair<const _TNode<_T>*,int>> TQueue2;
 const _TNode<_T>* pCur = m_pRoot;
 int index = 0;

 while( pCur != NULL)
 {
  for (int i = 0; i < 12 - index; ++i)
   cout << '/t';
  cout << pCur->data << endl;

  TQueue.push(pCur->pLeft);
  TQueue.push(pCur->pRight);
  ++index;
  pCur = TQueue.front();
  TQueue.pop();
 }
}

template<typename _T>
int CBinaryTree<_T>::Height() const
{
 return Height(m_pRoot);
}

template<typename _T>
int CBinaryTree<_T>::Height(const _TNode<_T>* pNode) const
{
 if (pNode == NULL)
  return 0;

 int left = 0;
 int right = 0;
 left = Height(pNode->pLeft);
 right = Height(pNode->pRight);
 
 return left>right?(left+1):(right+1);
}

原创粉丝点击