本文整理自:https://www.cnblogs.com/33debug/p/7248822.html,特此感谢!
一、相关概念
树是n( n>=0)个有限个数据的元素集合,它的数据的存储结构形状像一颗倒过来的树。根在上,叶在下:如图所示
1.一个独立的节点也可看作一棵树,它既为根节点,又为叶子节点;
2.一个节点也没有称作空树;
3.这是一颗典型的树,根节点为A;
4.一个节点只有唯一父节点。
节点: 结点包含数据和指向其它节点的指针。
根节点: 树第一个结点称为根节点。
结点的度: 结点拥有的子节点个数。
叶节点: 没有子节点的节点(度为0)。
父子节点: 一个节点father指向另一个节点child, 则child为孩子节点, father为父亲节点 。
兄弟节点: 具有相同父节点的节点互为兄弟节点。
节点的祖先: 从根节点开始到该节点所经的所有节点都可以称为该节点的祖先。
子孙: 以某节点为根的子树中任一节点都称为该节点的子孙。
树的高度: 树中距离根节点最远节点的路径长度。
如图示:
5.树的存储结构
struct TreeNode
{
DataType data; //节点值
TreeNode* _firistchild; //第一个孩子
TreeMode* _nextchild; //第二个孩子
...
};
有时候根据需要还会加入父节点,结构如下:
struct TreeNode { DataType data; //节点值 TreeNode* _parent; TreeNode* _firistchild; //第一个孩子 TreeMode* _nextchild; //第二个孩子 ... };
二、二叉树
1.二叉树:二叉树是一棵特殊的树, 二叉树每个节点最多有两个孩子结点, 分别称为左孩子和右孩子。如图:
2.存储结构
template <class T> struct TreeNode //定义二叉树结点 { TreeNode<T>* _left; //指向左子树的指针 TreeNode<T>* _right; //指向右子树的指针 T _data; //节点数据 TreeNode(const T& n) :_left(NULL) ,_right(NULL) ,_data(n) {} };
有时候根据需要还会加入父节点,结构如下:
template <class T> struct TreeNode //定义二叉树结点 { TreeNode<T>* _parent; //指向父节点的指针 TreeNode<T>* _left; //指向左子树的指针 TreeNode<T>* _right; //指向右子树的指针 T _data; //节点数据 TreeNode(const T& n) :_left(NULL) ,_right(NULL) ,_data(n) {} };
3.特殊的二叉树
满二叉树:高度为N的满二叉树有2^N - 1个节点的二叉树。
完全二叉树: 若设二叉树的深度为h, 除第 h 层外, 其它各层 (1~ h-1) 的结点数都达到最大个数, 第 h 层所有的结点都连续集中在最左
边, 这就是完全二叉树
对于上面这颗完全二叉树:
前序遍历(先根遍历): 根左右 【1 2 3 4 5 6】
中序遍历: 左根右 【3 2 4 1 6 5】
后序遍历(后根遍历): 左右根 【3 4 2 6 5 1】
层序遍 历: 一层层节点依次遍历【1 2 5 3 4 6】
三、对二叉树的相关操作
#pragma once #include <iostream> #include <queue> using namespace std; template <class T> struct BinaryTreeNode //定义二叉树结点 { BinaryTreeNode<T>* _left; //指向左子树的指针 BinaryTreeNode<T>* _right; //指向右子树的指针 T _data; //节点数据 BinaryTreeNode(const T& n) :_left(NULL) ,_right(NULL) ,_data(n) {} }; template <class T> class BinaryTree { typedef BinaryTreeNode<T> Node; public: BinaryTree() //空树 :_root(NULL) {} BinaryTree(const BinaryTree<T>& tree) //拷贝构造 { _root = _Copy(tree._root); } ~BinaryTree() //析构二叉树 { _Destroy(_root); _root = NULL; } BinaryTree<T>& operator=(const BinaryTree<T>& tree) //赋值运算符重载 { if (this != &tree) { _Destroy(_root); _root = _Copy(tree._root); } return *this } /*BinaryTree<T>& operator=(const BinaryTree<T>& tree) { swap(_root, tree._root); return *this; }*/ BinaryTree(T* a, size_t n, const T& invalid) { //invalid无效节点(#)//创建节点个数为N的二叉树 size_t index = 0; _root = _CreatTree(a, n, invalid, index); } void PrevOrder(){ //前序遍历二叉树递归法 _PrevOrder(_root); cout << endl; } void PrevOrderNonR() //前序遍历二叉树非递归法 { _PrevOrderNonR(_root); cout << endl; } void InOrder() //中序遍历二叉树递归法 { _InOrder(_root); cout << endl; } void InOrderNonR() //中序遍历二叉树非递归法 { _InOrderNonR(_root); cout << endl; } void PostOrder() //后序遍历二叉树递归法 { _PostOrder(_root); cout << endl; } void PostOrderNonR() //后序遍历二叉树非递归法 { _PostOrderNonR(); cout << endl; } void LevelOrder() //层序遍历二叉树递归法 { _LevelOrder(_root); cout << endl; } void LevelOrderNonR()//.queue//层序遍历二叉树非递归法 { _LevelOrderNonR(_root); cout << endl; } size_t Size(){ //二叉树总节点个数 return _Size(_root); } size_t CountLeafNode() //叶子节点 { return _CountLeafNode(_root); } size_t Depth() //高度 { return _Depth(_root); } size_t GetKLevelSize(size_t k) //第K层节点个数 { return _GetKLevelSize(_root, k); } Node* Find(const T& x) //查找节点 { return _Find(_root, x); } private: Node * _root; //根节点 Node* _CreatTree(T* a, size_t n, const T& invalid, size_t &index) { //创建二叉树树 Node* root = NULL; if (index < n && 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) //copy二叉树 { if (root == NULL) return NULL; Node* newroot = new Node(root->_data); newroot->_left = _Copy(root->_left); newroot->_right = _Copy(root->_right); } void _Destory(Node* root) //销毁二叉树树 { if (root == NULL) return; _Destory(root->_left); _Destory(root->_right); delete root; } };