数据结构之二叉树的简单操作

xiaoxiao2021-02-28  90

二叉树是数据结构——树的一个重要结构,可以实现很多算法,今天就来看一下二叉树的基本实现。

#include <iostream> #include <stack> #include <queue> #include <assert.h> using namespace std; template<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(T* a, size_t n,const T& invalid) //为了保证类的封装性,public的成员函数去调用protected的成员函数,意思是这里的函数全是形式上的函数 { size_t index = 0; _root = CreateTree(a,n,invalid,index); } void _PrevOrder() { PrevOrder(_root); cout << endl; } void _PrevOrderNorm() { PrevOrderNorm(_root); } void _LevelOrder() { LevelOrder(_root); } size_t Size() { return _Size(_root); } size_t LeafSize() { return _LeafSize(_root); } size_t GetKLevel(size_t k) { return _GetKLevel(k,_root); } Node* Find(const T& x) { return _Find(_root,x); } size_t Depth() { return _Depth(_root); } protected: //这里的函数才是真正算法的实现 Node* CreateTree(T* a, size_t n, const T& invalid, size_t& index) //运用递归创建一个二叉树 { Node* root = NULL; if ((a[index] != invalid)&&(index < n)) { root = new Node(a[index]); root->_left = CreateTree(a, n, invalid, ++index); root->_right = CreateTree(a, n, invalid, ++index); return root; } return root; } void PrevOrder(Node* root)// 先序遍历递归算法 { if (root == NULL) return; else { cout << root->_data << " "; //根节点 PrevOrder(root->_left);// 先序遍历左子树 PrevOrder(root->_right);// 先序遍历右子树 } } void PrevOrderNorm(Node* root) //先序遍历的非递归算法 { Node* cur = root; stack<Node*> s; while (cur || !s.empty()) { while (cur) { cout << cur->_data << " "; s.push(cur); cur = cur->_left; } Node* top = s.top(); s.pop(); //走到这,top(栈顶)节点的左子树已经遍历完毕,该访问右子树了 cur = top->_right;//访问右子树,又是先序遍历的子问题 } cout << endl; } void LevelOrder(Node* root) //使用队列先进先出的特点实现广度优先遍历 { queue<Node*> q; if (root!=NULL) q.push(root); while (!q.empty()) { Node* front = q.front(); //出队之前保存 cout << front->_data<<" "; q.pop(); if (front->_left != NULL) //出队之后将这个节点“接管”的下一层节点入队 q.push(front->_left); if (front->_right != NULL) q.push(front->_right); } cout << endl; } size_t _Size(Node* root)///获取二叉树节点个数 { if (root == NULL) return 0; else return 1 + _Size(root->_left) + _Size(root->_right); } size_t _LeafSize(Node* root) { if (root == NULL) return 0; else if ((root->_left == NULL) && (root->_right == NULL)) return 1; else return _LeafSize(root->_left) + _LeafSize(root->_right); } size_t _GetKLevel(size_t k, Node* root)//k层节点的个数 { assert(k > 0); if (root == NULL) return 0; else if (k == 1) return 1; else return _GetKLevel(k - 1, root->_left) + _GetKLevel(k - 1, root->_right); } Node* _Find(Node* root, const T& x)//查找值为x的节点 { if (root == NULL) return NULL; if (root->_data == x) return root; Node* left = _Find(root->_left, x); if (left != NULL) return left; else return _Find(root->_right, x); } size_t _Depth(Node* root)//获取深度 { if (root == NULL) return 0; else if (root->_left == NULL&&root->_right == NULL) return 1; else { size_t left = _Depth(root->_left); size_t right = _Depth(root->_right); return left > right ? 1 + left : 1 + right; } } protected: Node* _root; };以上就是一些简单的二叉树操作,其中遍历包括前序中序和后序,但是算法都基本一致,在此不在赘述。其余各算法要领均已经在注释中写明。

以下为测试代码:

void testbinarytree() { int a[10] = {1,2,3,'#','#',4,'#','#',5,6}; BinaryTree<int> t1(a,sizeof(a)/sizeof(a[0]),'#'); t1._PrevOrder(); t1._PrevOrderNorm(); t1._LevelOrder(); cout<<t1.Size()<<endl; cout << t1.LeafSize() << endl; cout << t1.GetKLevel(2) << endl; cout << t1.Find(3) << endl; cout << t1.Depth() << endl; }

转载请注明原文地址: https://www.6miu.com/read-76228.html

最新回复(0)