下面代码所用到的测试用例画成树的样子长这样:
创建树时给的是数组,用‘#’代表非法值,即该结点为空。
二叉树的递归实现:
#pragma once #include<iostream> #include<queue> using namespace std; template<class T> struct BinaryTreeNode { BinaryTreeNode(T value=0) :_value(value),_left(NULL),_right(NULL) {} T _value; BinaryTreeNode<T>* _left; BinaryTreeNode<T>* _right; }; template<class T> class BinaryTree { public: typedef BinaryTreeNode<T> Node; BinaryTree() {} BinaryTree(T* a,size_t size,const T& invalid) { size_t index = 0; _root=_CreatTree( a,size,index,invalid); } BinaryTree(const BinaryTree<T>& bt) { _root = _Copy(bt._root); } BinaryTree<T>& operator=(BinaryTree<T>& bt) { if (this != &bt) { BinaryTree<T> tmp(bt); swap(tmp._root,_root); } } ~BinaryTree() { _Distory(_root); } void PrevOrder() { _PrevOrder(_root); cout << endl; } void InOrder() { _InOrder(_root); cout << endl; } void PostOrder() { _PostOrder(_root); cout << endl; } void LevelOrder() //层序遍历 { _LevelOrder(_root); cout << endl; } size_t Size() { return _Size(_root); } size_t Depth() { return _Depth(_root); } size_t LeafSize() { return _LeafSize(_root); } size_t GetKLevel(size_t k) //第K层结点个数 { } protected: Node* _Distory(Node* root) { if (root) { _Distory(root->_left); _Distory(root->_right); Node* del = root; delete del; } return root; } Node* _CreatTree( T*a,size_t& index,const T& invalid) { Node* root = NULL; if ((index < size)&&(a[index] != invalid)) { root = new Node(a[index]); root->_left = _CreatTree(a,++index,invalid); root->_right = _CreatTree(a,invalid); } return root; } Node* _Copy(Node* copyroot) { Node* root = NULL; if (copyroot!=NULL) { root = new Node(copyroot->_value); root->_left = _Copy(copyroot->_left); root->_right = _Copy(copyroot->_right); } return root; } Node* _PrevOrder(Node* root) { if (root) { cout << root->_value << " "; _PrevOrder(root->_left); _PrevOrder(root->_right); } return root; } Node* _InOrder(Node* root) { if (root) { _InOrder(root->_left); cout << root->_value<<" "; _InOrder(root->_right); } return root; } Node* _PostOrder(Node* root) { if (root) { _PostOrder(root->_left); _PostOrder(root->_right); cout << root->_value << " "; } return root; } void _LevelOrder(Node* root) { queue<Node*> q; q.push(root); while (!q.empty()) { Node* tmp = q.front(); cout << tmp->_value<<" "; if (tmp->_left) q.push(tmp->_left); if (tmp->_right) q.push(tmp->_right); q.pop(); } } size_t _Size(Node* root) { size_t size = 0; if (root) { size = _Size(root->_left) + _Size(root->_right)+1; } return size; } size_t _Depth(Node* root) { size_t depth1 = 0; size_t depth2 = 0; if (root) { depth1 = _Depth(root->_left) + 1; depth2 = _Depth(root->_right) + 1; } return depth1 > depth2 ? depth1 : depth2; } size_t _LeafSize(Node* root) { if (root == NULL) return 0; else if (root->_left == NULL&&root->_right == NULL) return 1; return _LeafSize(root->_left) + _LeafSize(root->_right); } private: Node* _root; }; void test() { int array[10] = { 1,2,3,'#',4,5,6 }; int array1[15] = { 1,6,7,8 }; BinaryTree<int> bt(array,10,'#'); bt.PrevOrder(); bt.InOrder(); bt.PostOrder(); cout << bt.Size() << endl; cout << bt.Depth() << endl; cout << bt.LeafSize() << endl; BinaryTree<int> bt2(array1,15,'#'); cout << bt2.Depth() << endl; cout << bt2.LeafSize() << endl; BinaryTree<int> bt3(bt); bt3.PrevOrder(); BinaryTree<int> bt4=bt3; bt4.PrevOrder(); bt4.LevelOrder(); }
递归的好处在于代码简练。但递归不容易理解。
非递归的二叉树(面试经常会考的):
#pragma once #include<iostream> #include<cassert> #include<queue> #include<stack> using namespace std; template<class T> struct BinaryTreeNode { BinaryTreeNode(T value = 0) :_value(value),_right(NULL) {} T _value; BinaryTreeNode<T>* _left; BinaryTreeNode<T>* _right; }; template<class T> class BinaryTree { public: typedef BinaryTreeNode<T> Node; BinaryTree() {} explicit BinaryTree(T* a,const T& invalid) //构造函数,创建一棵树。 { stack<Node*> s; size_t index = 0; Node* cur = NULL; while (index < size) { while ((index < size) && (a[index] != invalid)) { if (index == 0) { _root = new Node(a[index++]); cur = _root; } else { cur->_left = new Node(a[index++]); cur = cur->_left; } s.push(cur); } index++; Node* top = s.top(); s.pop(); if ((index < size) && (a[index] != invalid)) { cur = top; cur->_right = new Node(a[index++]); cur = cur->_right; s.push(cur); } } } BinaryTree(const BinaryTree<T>& bt) //拷贝构造 { Node* cur = bt._root; Node* root = NULL; stack<Node*>s; stack<Node*>s1; while (cur || !s.empty()) { while (cur) { s.push(cur); if (root == NULL) { root = new Node(cur->_value); _root = root; } else { root->_left = new Node(cur->_value); root = root->_left; } cur = cur->_left; s1.push(root); } Node* top = s.top(); Node* top1 = s1.top(); s.pop(); s1.pop(); cur = top->_right; if (cur) { root = top1; root->_right = new Node(cur->_value); root = root->_right; cur = cur->_left; } } } BinaryTree<T>& operator=(BinaryTree<T> bt) { swap(_root,bt._root); return *this; } void PrevOrderNoR() { Node* cur = _root; stack<Node*> s; while (cur || !s.empty()) { while (cur) { cout << cur->_value << " "; s.push(cur); cur = cur->_left; } Node* top = s.top(); s.pop(); cur = top->_right; } cout << endl; } void InOrderNoR() { Node* cur = _root; stack<Node*> s; while (cur || !s.empty()) { while (cur) { s.push(cur); cur = cur->_left; } Node* top = s.top(); s.pop(); cout << top->_value << " "; cur = top->_right; } cout << endl; } void PostOrderNoR() { Node* cur = _root; Node* prev = NULL; stack<Node*> s; while (cur || !s.empty()) { while (cur) { s.push(cur); cur = cur->_left; } Node* top = s.top(); if ((top->_right == NULL) || (prev == top->_right)) { prev = top; cout << top->_value << " "; s.pop(); //cur = top->_right; } else cur = top->_right; } cout << endl; } size_t SizeNoR() { size_t size = 0; Node* cur = _root; stack<Node*> s; while (cur || !s.empty()) { while (cur) { s.push(cur); size++; cur = cur->_left; } Node* top = s.top(); s.pop(); cur = top->_right; } return size; } size_t DepthNoR() { if (_root == NULL) return 0; size_t depth = 0; Node* cur = NULL; queue<Node*> q; size_t VisitNum = 0; //有多少数据出栈 size_t NodeNum = 1; size_t LeveNum = 1; //每一层最后一个数据的序号 q.push(_root); while (!q.empty()) { cur = q.front(); q.pop(); VisitNum++; if (cur->_left) { NodeNum++; q.push(cur->_left); } if (cur->_right) { NodeNum++; q.push(cur->_right); } if (LeveNum == VisitNum) { depth++; LeveNum = NodeNum; } } return depth; } size_t LeveNum() //叶子节点个数 { size_t count = 0; Node* cur = _root; stack<Node*> s; while (cur || !s.empty()) { while (cur) { s.push(cur); if ((cur->_left == NULL) && (cur->_right == NULL)) count++; cur = cur->_left; } Node* top = s.top(); s.pop(); cur = top->_right; } return count; } size_t GetKLeve(size_t k) //得到第k层结点个数。 { assert(k <= DepthNoR()); if (k == 1) return 1; queue<Node*>q; size_t NodeNum = 1; size_t LeveNum = 1; size_t VisitNum = 0; size_t leve = 1; q.push(_root); while (!q.empty()) { Node* cur = q.front(); q.pop(); VisitNum++; if (cur->_left) { q.push(cur->_left); NodeNum++; } if (cur->_right) { q.push(cur->_right); NodeNum++; } if (LeveNum == VisitNum) { leve++; if (leve == k) break; LeveNum = NodeNum; } } return NodeNum - VisitNum; } private: Node* _root; }; void test() { int array[10] = { 1,6 }; BinaryTree<int> bt(array,'#'); bt.PrevOrderNoR(); bt.InOrderNoR(); bt.PostOrderNoR(); BinaryTree<int> bt1(bt); bt1.PrevOrderNoR(); BinaryTree<int> bt2 = bt1; bt2.PrevOrderNoR(); cout << bt.SizeNoR() << endl; cout << bt.DepthNoR() << endl; cout << bt.LeveNum() << endl; cout << bt.GetKLeve(3) << endl; }可以看到,非递归相对来说代码量能多点,但是比较容易理解,而且几个遍历过程代码十分相似,理解其中一个,后面几个都是类似的。 原文链接:https://www.f2er.com/datastructure/382438.html