#include <assert.h>
#include <iostream>
using namespace std;
#include <stack>
#include <queue>
template<class T>
struct BinaryTreeNode
{
BinaryTreeNode<T>* _left;
BinaryTreeNode<T>* _right;
T _data;
BinaryTreeNode(const T& x)
:_left(NULL)
,_right(NULL)
,_data(x)
{}
};
template<class T>
class BinaryTree
{
public:
BinaryTree()
:_root(NULL)
{}
BinaryTree(const T* a, size_t size, const T& invalid)
{
size_t index = 0;
_root = _CreateTree(a, size, index, invalid);
}
~BinaryTree()
{
_DestroyTree(_root);
_root = NULL;
}
BinaryTree(const BinaryTree<T>& t)
{
_root = _CopyTree(t._root);
}
//賦值運算符重載的傳統(tǒng)寫法
/*BinaryTree<T>& operator=(const BinaryTree& t)
{
if (this != &t)
{
_DestroyTree(_root);
_root = _CopyTree(t._root);
}
return *this;
}*/
//賦值運算符重載的現(xiàn)代寫法
BinaryTree<T>& operator=(BinaryTree<T> t)
{
swap(_root, t._root);
return *this;
}
//遞歸前序遍歷
void PreOrderTraverse()
{
_PreOrderTraverse(_root);
cout<<endl;
}
//遞歸中序遍歷
void InOrderTraverse()
{
_InOrderTraverse(_root);
cout<<endl;
}
//遞歸后序遍歷
void PostOrderTraverse()
{
_PostOrderTraverse(_root);
cout<<endl;
}
//非遞歸層序遍歷
void LevelOrderTraverse()
{
if (NULL == _root)
{
return;
}
queue<BinaryTreeNode<T>*> q;
q.push(_root);
while (!q.empty())
{
BinaryTreeNode<T>* front = q.front();
q.pop();
cout<<front._data<<" ";
if (front->_left)
{
q.push(front->_left);
}
if (front->_right)
{
q.push(front->_right);
}
}
}
//非遞歸前序遍歷
void PreOrderTraverse_NonR()
{
if (NULL == _root)
{
return;
}
stack<BinaryTreeNode<T>*> s;
s.push(_root);
while (!s.empty())//當棧為空時遍歷完成
{
//先訪問根節(jié)點
BinaryTreeNode<T>* top = s.top();
s.pop();
cout<<top->_data<<" ";
//右節(jié)點存在時先入棧,后出棧
if (top->_right)
{
s.push(top->_right);
}
//左結點存在時后入棧,先出棧
if (top->_left)
{
s.push(top->_left);
}
}
cout<<endl;
}
//非遞歸中序遍歷
void InOrderTraverse_NonR()
{
if (NULL == _root)
{
return;
}
stack<BinaryTreeNode<T>*> s;
BinaryTreeNode<T>* cur = _root;
while (cur || !s.empty())
{
//左結點全部入棧
while (cur)
{
s.push(cur);
cur = cur->_left;
}
if (!s.empty())
{
BinaryTreeNode<T>* top = s.top();
cout<<top->_data<<" ";
s.pop();
cur = top->_right;//將棧頂結點的右節(jié)點看作子樹的根節(jié)點
}
}
cout<<endl;
}
//非遞歸后序遍歷
void PostOrderTraverse_NonR()
{
if (NULL == _root)
{
return;
}
stack<BinaryTreeNode<T>*> s;
BinaryTreeNode<T>* cur = _root;
BinaryTreeNode<T>* pre = NULL;
while (cur || !s.empty())//當前結點為空和棧為空同時滿足時遍歷完成
{
//左結點全部入棧
while (cur)
{
s.push(cur);
cur = cur->_left;
}
BinaryTreeNode<T>* top = s.top();
if (NULL == top->_right || pre == top->_right)//若當前結點的右結點為空或者右節(jié)點已經(jīng)訪問過,可以訪問該結點
{
cout<<top->_data<<" ";
pre = top;
s.pop();
}
else//該結點的右節(jié)點不為空且未被訪問
{
cur = top->_right;//將該結點的右節(jié)點看作子樹的根節(jié)點
}
}
cout<<endl;
}
//求結點數(shù)
size_t Size()
{
size_t size = 0;
_Size(_root, size);
return size;
}
//求深度
size_t Depth()
{
return _Depth(_root);
}
//求葉子結點數(shù)
size_t LeafSize()
{
size_t leafSize = 0;
_LeafSize(_root, leafSize);
return leafSize;
}
//求第K層結點數(shù)
size_t GetKLevel(const size_t& k)
{
return _GetKLevel(_root, k);
}
protected:
BinaryTreeNode<T>* _CreateTree(const T* a, size_t size, size_t& index, const T& invalid)
{
BinaryTreeNode<T>* root = NULL;
if (index < size && a[index] != invalid)
{
root = new BinaryTreeNode<T>(a[index]);
root->_left = _CreateTree(a, size, ++index, invalid);
root->_right = _CreateTree(a, size, ++index, invalid);
}
return root;
}
void _DestroyTree(BinaryTreeNode<T>* root)
{
if (NULL == root)
{
return;
}
if (NULL == root->_left && NULL == root->_right)
{
delete root;
root = NULL;
return;
}
_DestroyTree(root->_left);
_DestroyTree(root->_right);
delete root;
}
BinaryTreeNode<T>* _CopyTree(BinaryTreeNode<T>* root)
{
if (NULL == root)
{
return NULL;
}
BinaryTreeNode<T>* newRoot = new BinaryTreeNode<T>(root->_data);
newRoot->_left = _CopyTree(root->_left);
newRoot->_right = _CopyTree(root->_right);
return newRoot;
}
void _PreOrderTraverse(BinaryTreeNode<T>* root)
{
if (NULL == root)
{
return;
}
cout<<root->_data<<" ";
_PreOrderTraverse(root->_left);
_PreOrderTraverse(root->_right);
}
void _InOrderTraverse(BinaryTreeNode<T>* root)
{
if (NULL == root)
{
return;
}
_InOrderTraverse(root->_left);
cout<<root->_data<<" ";
_InOrderTraverse(root->_right);
}
void _PostOrderTraverse(BinaryTreeNode<T>* root)
{
if (NULL == root)
{
return;
}
_PostOrderTraverse(root->_left);
_PostOrderTraverse(root->_right);
cout<<root->_data<<" ";
}
//_Size方法1:
/*size_t _Size(BinaryTreeNode<T>* root)
{
if (NULL == root)
{
return;
}
return _Size(root->left) + _Size(root->_right) + 1;
}*/
//_Size方法2:(存在線程安全問題)
/*size_t _Size(BinaryTreeNode<T>* root)
{
static size_t size = 0;
if (NULL == root)
{
return 0;
}
else
{
++size;
}
_Size(root->_left);
_Size(root->_right);
return size;
}*/
//_Size方法3:
void _Size(BinaryTreeNode<T>* root, size_t& size)
{
if (NULL == root)
{
return;
}
else
{
++size;
}
_Size(root->_left, size);
_Size(root->_right, size);
}
size_t _Depth(BinaryTreeNode<T>* root)
{
if (NULL == root)
{
return 0;
}
size_t leftDepth = _Depth(root->_left);
size_t rightDepth = _Depth(root->_right);
return leftDepth > rightDepth ? leftDepth+1 : rightDepth+1;
}
void _LeafSize(BinaryTreeNode<T>* root, size_t& leafSize)
{
if (NULL == root)
{
return;
}
if (NULL == root->_left && NULL == root->_right)
{
++leafSize;
return;
}
_LeafSize(root->_left, leafSize);
_LeafSize(root->_right, leafSize);
}
size_t _GetKLevel(BinaryTreeNode<T>* root, const size_t& k)
{
assert(k > 0);
if (NULL == root)
{
return 0;
}
if (k == 1)
{
return 1;
}
return _GetKLevel(root->_left, k-1) + _GetKLevel(root->_right, k-1);
}
protected:
BinaryTreeNode<T>* _root;
};
void BinaryTreeTest()
{
int a[] = {1, 2, 3, '#', '#', 4, '#', '#', 5, 6};
BinaryTree<int> t(a, sizeof(a)/sizeof(a[0]), '#');
cout<<"遞歸前序遍歷:";
t.PreOrderTraverse();
cout<<"遞歸中序遍歷:";
t.InOrderTraverse();
cout<<"遞歸后序遍歷:";
t.PostOrderTraverse();
cout<<"非遞歸前序遍歷:";
t.PreOrderTraverse_NonR();
cout<<"非遞歸中序遍歷:";
t.InOrderTraverse_NonR();
cout<<"非遞歸后序遍歷:";
t.PostOrderTraverse_NonR();
cout<<"Size:"<<t.Size()<<endl;
cout<<"Depth:"<<t.Depth()<<endl;
cout<<"LeafSize:"<<t.LeafSize()<<endl;
cout<<"Get3Level:"<<t.GetKLevel(3)<<endl;
BinaryTree<int> t2(t);
cout<<"t2:";
t2.PreOrderTraverse();
BinaryTree<int> t3;
t3 = t2;
cout<<"t3:";
t3.PreOrderTraverse();
}
int main()
{
BinaryTreeTest();
return 0;
}生成的二叉樹如下圖:
為天壇街道等地區(qū)用戶提供了全套網(wǎng)頁設計制作服務,及天壇街道網(wǎng)站建設行業(yè)解決方案。主營業(yè)務為成都網(wǎng)站建設、做網(wǎng)站、天壇街道網(wǎng)站設計,以傳統(tǒng)方式定制建設網(wǎng)站,并提供域名空間備案等一條龍服務,秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!

測試結果:

分享標題:C++實現(xiàn)二叉樹
網(wǎng)頁地址:http://www.yijiale78.com/article30/ihojpo.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供云服務器、網(wǎng)站策劃、網(wǎng)站改版、網(wǎng)站維護、外貿建站、網(wǎng)站建設
聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)