~二叉树~

来源:互联网 发布:p2p网络正在连接 编辑:程序博客网 时间:2024/06/07 09:08

       我们都知道,二叉树是一颗特殊的树,如下图所示,可二叉树又该如何用代码实现呢?那就往下翻呗!

 

1.定义结点的结构体

template <class T>struct BinaryTreeNode  //定义结点的结构体{T _data;BinaryTreeNode<T> *_left;BinaryTreeNode<T> *_right;BinaryTreeNode(const T& x):_data(x),_left(NULL),_right(NULL){}};

2.二叉树的四个默认成员函数

BinaryTree(T *a, size_t n, const T &invalid = T())  //构造函数{size_t index = 0;_root = _CreatTree(a, n, invalid, index);}BinaryTree(const BinaryTree<T> &t)  //拷贝构造{_root = _Copy(t._root);}//传统写法BinaryTree<T>& operator=(const BinaryTree<T> &t)  //赋值运算符重载{if(this != &t){Node *newRoot = _Copy(t._root);_Destroy(_root);_root = newRoot;}return *this;}//现代写法BinaryTree<T>& operator=(BinaryTree<T> t)  //赋值运算符重载{swap(_root, t._root);return *this;}~BinaryTree()  //析构函数{_Destroy(_root);}
Node* _CreatTree(T *a, size_t n, const T &invalid, size_t &index){Node *root = NULL;if(a[index] != invalid){root = new Node(a[index]);root->_left = _CreatTree(a, n, invalid, ++index);root->_right = _CreatTree(a, n, invalid, ++index);}return root;}Node* _Copy(Node *root){if(NULL == root){return NULL;}Node *newNode = new Node(root->_data);newNode->_left = _Copy(root->_left);newNode->_right = _Copy(root->_right);return newNode;}void _Destroy(Node *root){if(NULL == root){return;}_Destroy(root->_left);_Destroy(root->_right);delete root;}

3.4种遍历操作

void PrevOrder()  //前序{_PrevOrder(_root);cout<<endl;}void _PrevOrder(Node* root){if(root == NULL){return;}cout<<root->_data<<" ";_PrevOrder(root->_left);_PrevOrder(root->_right);}void InOrder()  //中序{_InOrder(_root);cout<<endl;}void _InOrder(Node* root){if(root == NULL){return;}_InOrder(root->_left);cout<<root->_data<<" ";_InOrder(root->_right);}void PastOrder()  //后序{_PastOrder(_root);cout<<endl;}void _PastOrder(Node* root){if(root == NULL){return;}_PastOrder(root->_left);_PastOrder(root->_right);cout<<root->_data<<" ";}void LevelOrder()  //层序(以当前结点带入下一层结点){queue<Node *> q;if(_root){q.push(_root);}while(!q.empty()){Node *front = q.front();cout<<front->_data<<" ";q.pop();if(front->_left){q.push(front->_left);}if(front->_right){q.push(front->_right);}}cout<<endl;}

4.结点个数

size_t Size(){size_t count = 0;return _Size(_root, count);}size_t _Size(Node *root, size_t &count){if(NULL == root){return 0;}++count;_Size(root->_left, count);_Size(root->_right, count);return count;}

5.叶子结点个数

size_t GetLeafSize(){size_t count = 0;_GetLeafSize(_root, count);return count;}void _GetLeafSize(Node *root, size_t &count){if(NULL == root){return;}if((root->_left == NULL) && (root->_right == NULL)){++count;}_GetLeafSize(root->_left, count);_GetLeafSize(root->_right, count);}

6.第k层结点个数

size_t GetKLevelSize(size_t k)  //第k层结点个数{assert(k > 0);return _GetKLevelSize(_root, k);}size_t _GetKLevelSize(Node* root, size_t k){if(root == NULL){return 0;}if(k == 1){return 1;}return _GetKLevelSize(root->_left, k-1) + _GetKLevelSize(root->_right, k-1);}

7.树的高度

size_t Depth(){return _Depth(_root);}size_t _Depth(Node *root){if(NULL == root){return 0;}int left = _Depth(root->_left);int right = _Depth(root->_right);return left > right ? left+1 : right+1;}

8.查找结点

Node* Find(const T& x){return _Find(_root, x);}Node* _Find(Node* root, const T& x){if(NULL == root){return NULL;}if(root->_data == x){return root;}Node *ret = _Find(root->_left, x);if(ret){return ret;}return _Find(root->_right, x);}

为方便起见,我们用模版来定义数据的类型。

 

完整的代码及测试用例如下:

#pragma oncetemplate <class T>struct BinaryTreeNode  //定义结点的结构体{T _data;BinaryTreeNode<T> *_left;BinaryTreeNode<T> *_right;BinaryTreeNode(const T& x):_data(x),_left(NULL),_right(NULL){}};template <class T>class BinaryTree{typedef BinaryTreeNode<T> Node;public:BinaryTree()  //构造函数:_root(NULL){}BinaryTree(T *a, size_t n, const T &invalid = T())  //构造函数{size_t index = 0;_root = _CreatTree(a, n, invalid, index);}BinaryTree(const BinaryTree<T> &t)  //拷贝构造{_root = _Copy(t._root);}//BinaryTree<T>& operator=(const BinaryTree<T> &t)  //赋值运算符重载//{//if(this != &t)//{//Node *newRoot = _Copy(t._root);//_Destroy(_root);//_root = newRoot;//}//return *this;//}//现代写法BinaryTree<T>& operator=(BinaryTree<T> t)  //赋值运算符重载{swap(_root, t._root);return *this;}~BinaryTree()  //析构函数{_Destroy(_root);}//增删查改  没有意义  关注的是递归结构void PrevOrder(){_PrevOrder(_root);cout<<endl;}void InOrder(){_InOrder(_root);cout<<endl;}void PastOrder(){_PastOrder(_root);cout<<endl;}void LevelOrder()  //层序(以当前结点带入下一层结点){queue<Node *> q;if(_root){q.push(_root);}while(!q.empty()){Node *front = q.front();cout<<front->_data<<" ";q.pop();if(front->_left){q.push(front->_left);}if(front->_right){q.push(front->_right);}}cout<<endl;}//size_t Size()//{//return _Size(_root);//}size_t Size(){size_t count = 0;return _Size(_root, count);}size_t GetLeafSize(){size_t count = 0;_GetLeafSize(_root, count);return count;//return _GetLeafSize(_root);}size_t GetKLevelSize(size_t k)  //第k层结点个数{assert(k > 0);return _GetKLevelSize(_root, k);}size_t Depth(){return _Depth(_root);}Node* Find(const T& x){return _Find(_root, x);}protected:Node* _CreatTree(T *a, size_t n, const T &invalid, size_t &index){Node *root = NULL;//if((index < n) && (a[index] != invalid))  当int array[13] = {1,2,3,'#','#',4,'#',5,6};if(a[index] != invalid){root = new Node(a[index]);root->_left = _CreatTree(a, n, invalid, ++index);root->_right = _CreatTree(a, n, invalid, ++index);}return root;}Node* _Copy(Node *root){if(NULL == root){return NULL;}Node *newNode = new Node(root->_data);newNode->_left = _Copy(root->_left);newNode->_right = _Copy(root->_right);return newNode;}void _Destroy(Node *root){if(NULL == root){return;}_Destroy(root->_left);_Destroy(root->_right);delete root;}void _PrevOrder(Node* root){if(root == NULL){return;}cout<<root->_data<<" ";_PrevOrder(root->_left);_PrevOrder(root->_right);}void _InOrder(Node* root){if(root == NULL){return;}_InOrder(root->_left);cout<<root->_data<<" ";_InOrder(root->_right);}void _PastOrder(Node* root){if(root == NULL){return;}_PastOrder(root->_left);_PastOrder(root->_right);cout<<root->_data<<" ";}//size_t _Size(Node *root)//{//if(NULL == root)//{//return 0;//}//return _Size(root->_left) + _Size(root->_right) + 1;////有问题(存在线程安全的问题——解决方法:加锁)////if(root == NULL)////{////return 0;////}////static size_t count = 0;////++count;////_Size(root->_left);////_Size(root->_right);////return count;//}size_t _Size(Node *root, size_t &count){if(NULL == root){return 0;}++count;_Size(root->_left, count);_Size(root->_right, count);return count;}void _GetLeafSize(Node *root, size_t &count){if(NULL == root){return;}if((root->_left == NULL) && (root->_right == NULL)){++count;}_GetLeafSize(root->_left, count);_GetLeafSize(root->_right, count);}//size_t _GetLeafSize(Node *root)//{//if(NULL == root)//{//return 0;//}//if((root->_left == NULL) && (root->_right == NULL))//{//return 1;//}//return _GetLeafSize(root->_left) + _GetLeafSize(root->_right);//}size_t _GetKLevelSize(Node* root, size_t k){if(root == NULL){return 0;}if(k == 1){return 1;}return _GetKLevelSize(root->_left, k-1) + _GetKLevelSize(root->_right, k-1);}size_t _Depth(Node *root){if(NULL == root){return 0;}int left = _Depth(root->_left);int right = _Depth(root->_right);return left > right ? left+1 : right+1;}Node* _Find(Node* root, const T& x){if(NULL == root){return NULL;}if(root->_data == x){return root;}Node *ret = _Find(root->_left, x);if(ret){return ret;}return _Find(root->_right, x);}protected:Node* _root;};void TestBinaryTree(){int array[13] = {1,2,3,'#','#',4,'#','#',5,6,'#','#','#'};BinaryTree<int> t1(array, sizeof(array)/sizeof(array[0]), '#');BinaryTree<int> t2(t1);BinaryTree<int> t3;t3 = t1;t1.PrevOrder();t2.PrevOrder();t2.PrevOrder();cout<<endl;t1.InOrder();t2.InOrder();t3.InOrder();cout<<endl;t1.PastOrder();t2.PastOrder();t3.PastOrder();cout<<endl;t1.LevelOrder();t2.LevelOrder();t3.LevelOrder();cout<<endl;cout<<t1.Size()<<endl;cout<<endl;cout<<t1.GetLeafSize()<<endl;cout<<endl;cout<<t1.GetKLevelSize(3)<<endl;cout<<endl;cout<<t1.Depth()<<endl;cout<<endl;cout<<t1.Find(3)->_data<<endl;cout<<endl;t1.PrevOrderNonR();cout<<endl;t1.InOrderNonR();cout<<endl;t1.PastOrderNonR();}
0 0