最近开始复习数据结构,感觉脑子不好使,特此记录一下,以便日后查看,也希望能给大家一些帮助!
类定义和一些函数接口:
template<class T>
struct BinaryTreeNode
{
BinaryTreeNode(T data)
:_data(data),
_left(NULL),
_right(NULL)
{}
BinaryTreeNode<T>* _left;
BinaryTreeNode<T>* _right;
T _data;
};
template<class T>
class BinaryTree
{
typedef BinaryTreeNode<T> Node;
public:
BinaryTree();
BinaryTree(T* arr, size_t size, const T& value);
//BinaryTree(const BinaryTree<T>& other);
//BinaryTree<T>& operator=(const BinaryTree<T>& other);
//~BinaryTree();
//递归遍历
void PreOrder();
void InOrder();
void PostOrder();
//迭代遍历
void PreOrder_NoR();
void InOrder_NoR();
void PostOrder_NoR();
void LevelOrder();
size_t Size();
size_t Depth();
size_t LeafSize();
下面时完整的代码:
#include <iostream>
#include <assert.h>
#include <queue>
#include <stack>
using namespace std;
template<class T>
struct BinaryTreeNode
{
BinaryTreeNode(T data)
:_data(data),
_left(NULL),
_right(NULL)
{}
BinaryTreeNode<T>* _left;
BinaryTreeNode<T>* _right;
T _data;
};
template<class T>
class BinaryTree
{
typedef BinaryTreeNode<T> Node;
public:
BinaryTree();
BinaryTree(T* arr, size_t size, const T& value);
BinaryTree(const BinaryTree<T>& other);
//BinaryTree<T>& operator=(BinaryTree<T>& other);
BinaryTree<T>& operator=(BinaryTree<T> other);
~BinaryTree();
//递归遍历
void PreOrder();
void InOrder();
void PostOrder();
//迭代遍历
void PreOrder_NoR();
void InOrder_NoR();
void PostOrder_NoR();
void LevelOrder();
size_t Size();
size_t Depth();
size_t LeafSize();
protected:
void _PreOrder(Node* root)
{
if (root== NULL)
{
return;
}
else
{
cout << root->_data << " ";
_PreOrder(root->_left);
_PreOrder(root->_right);
}
}
void _InOrder(Node* root)
{
if (root == NULL)
{
return;
}
_InOrder(root->_left);
cout << root->_data << " ";
_InOrder(root->_right);
}
void _PostOrder(Node* root)
{
if (root == NULL)
{
return;
}
_PostOrder(root->_left);
_PostOrder(root->_right);
cout << root->_data << " ";
}
Node* CreateTree(T* arr, size_t size,size_t& index, const T& value)
{
Node* root = NULL;
if (index <size && arr[index] != value)
{
root = new Node(arr[index]);
root->_left = CreateTree(arr, size,++index, value);
root->_right = CreateTree(arr, size,++index, value);
}
return root;
}
size_t _Size(Node* root)
{
if (root == NULL)
{
return 0;
}
return _Size(root->_left) + _Size(root->_right) + 1;
}
size_t _Depth(Node* root)
{
if (root == NULL)
{
return 0;
}
size_t left = _Depth(root->_left)+1;
size_t right = _Depth(root->_right)+1;
return left > right ? left : right;
}
size_t _LeafSize(Node* root)
{
if (root == NULL)
return 0;
if (root->_left == NULL &&root->_right == NULL)
{
return 1;
}
return _LeafSize(root->_left) + _LeafSize(root->_right);
}
Node* CopyTree(Node* root)
{
Node* Croot = NULL;
if (NULL == root)
return NULL;
Croot = new Node(root->_data);
Croot->_left = CopyTree(root->_left);
Croot->_right = CopyTree(root->_right);
return Croot;
}
void _destroy(Node* root)
{
if (root)
{
_destroy(root->_left);
_destroy(root->_right);
delete root;
root = NULL;
}
}
protected:
Node* _root;
};
template<class T>
BinaryTree<T>::BinaryTree()
{
_root = NULL;
}
template<class T>
BinaryTree<T>::BinaryTree(T* arr, size_t size, const T& value)
{
size_t index = 0;
_root = CreateTree(arr, size,index, value);
}
template<class T>
BinaryTree<T>::~BinaryTree()
{
_destroy(_root);
}
template<class T>
BinaryTree<T>::BinaryTree(const BinaryTree<T>& other)
{
_root = CopyTree(other._root);
}
//方法一
//template<class T>
//BinaryTree<T>& BinaryTree<T>::operator=(BinaryTree<T>& other)
//{
// if (this != &other)
// {
// this->~BinaryTree();
// }
// _root = CopyTree(other._root);
// return *this;
//}
//方法二
template<class T>
BinaryTree<T>& BinaryTree<T>::operator=(BinaryTree<T> other)
{
swap(_root, other._root);
return *this;
}
template<class T>
void BinaryTree<T>::PreOrder()
{
_PreOrder(_root);
cout << endl;
}
template<class T>
void BinaryTree<T>::PreOrder_NoR()
{
Node* cur = _root;
stack<Node*> s;
while (cur || !s.empty())
{
while (cur)
{
cout << cur->_data << " ";
s.push(cur);
cur = cur->_left;
}
if (!s.empty())
{
cur = s.top();
s.pop();
cur = cur->_right;
}
}
cout << endl;
}
template<class T>
void BinaryTree<T>::InOrder()
{
_InOrder(_root);
cout << endl;
}
template<class T>
void BinaryTree<T>::InOrder_NoR()
{
Node* cur = _root;
stack<Node*> s;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cur = cur->_left;
}
Node* temp = s.top();
s.pop();
cout << temp->_data << " ";
cur = temp->_right;
}
cout << endl;
}
template<class T>
void BinaryTree<T>::PostOrder_NoR()
{
//要保证根结点在左孩子和右孩子访问之后才能访问,
//因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;
//或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。
//若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,
//左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
Node* cur = _root;
Node* prev = NULL;
stack<Node*> st;
if (_root==NULL)
{
return;
}
st.push(cur);
while (!st.empty())
{
cur = st.top();
if ((cur->_left == NULL && cur->_right == NULL)\
|| (prev != NULL) && (prev == cur->_left || prev == cur->_right))
{//如果无左右子树,访问,或者左右子树已经访问过,也可以访问。
cout << cur->_data << " ";
st.pop();
prev = cur;
}
else
{
if (cur->_right)
{
st.push(cur->_right);
}
if (cur->_left)
{
st.push(cur->_left);
}
}
}
cout << endl;
}
template<class T>
void BinaryTree<T>::PostOrder()
{
_PostOrder(_root);
cout << endl;
}
template<class T>
void BinaryTree<T>::LevelOrder()
{
queue<Node*> qu;
if (_root)
{
qu.push(_root);
}
while (!qu.empty())
{
Node* front = qu.front();
qu.pop();
cout << front->_data << " ";
if (front->_left)
{
qu.push(front->_left);
}
if (front->_right)
{
qu.push(front->_right);
}
}
cout << endl;
}
template<class T>
size_t BinaryTree<T>::Size()
{
return _Size(_root);
}
/*void _size()
{
gsize = 0;//每次必须初始化为0 ,否则会有叠加;
_size(root);
return gsize;
}
//定义一个gsize的全局变量,根据其作用域,遍历树,++gsize即可。
//存在的问题是每次必须初始化为0,否则会有bug;两个对象共享一个全局变量的bug。
//这种全局或者静态的全局变量存在线程安全的问题,我们可以在栈上设置一个共享的变量,用引用, int &size。
//size在递归的过程中是独立存在的;
size_t _Size(Node* root)
{
if (root == NULL)
{
return 0;
}
gsize++;
_Size(root->_left);
_Size(root->_right);
}*/
template<class T>
size_t BinaryTree<T>::Depth()
{
return _Depth(_root);
}
template<class T>
size_t BinaryTree<T>::LeafSize()
{
return _LeafSize(_root);
}
下面是测试代码:
void test()
{
int arr[10] = {1,2,3,'#','#',4,'#','#',5,6};
BinaryTree<int> t1(arr, 10, '#');
cout << "递归先序遍历" << endl;
t1.PreOrder();
cout << "递归中序遍历" << endl;
t1.InOrder();
cout << "递归后序遍历" << endl;
t1.PostOrder();
cout << "非递归先序遍历" << endl;
t1.PreOrder_NoR();
cout << "非递归中序遍历" << endl;
t1.InOrder_NoR();
cout << "非递归后序遍历" << endl;
t1.PostOrder_NoR();
cout << "层次遍历" << endl;
t1.LevelOrder();
cout<<"Size == "<<t1.Size()<<endl;
cout << "Depth == " << t1.Depth() << endl;
cout << "LeafSize == " << t1.LeafSize() << endl;
}
int main()
{
test();
return 0;
}
运行结果如图所示: