最近开始复习数据结构,感觉脑子不好使,特此记录一下,以便日后查看,也希望能给大家一些帮助!
类定义和一些函数接口:
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; }运行结果如图所示: