二叉树基础
来源:互联网 发布:淘宝如何自动发卡密 编辑:程序博客网 时间:2024/05/16 14:04
二叉树:二叉树是一棵特殊的树,二叉树每个节点最多有两个孩子结点,分别称为左孩子和右孩子。
二叉树节点结构:
struct BinaryTreeNode{T _data;//数据BinaryTreeNode<T>* _left;//指向左子树BinaryTreeNode<T>* _right;//指向右子树BinaryTreeNode(const T& d):_data(d),_left(NULL),_right(NULL){}};
二叉树的创建:
Node* _CreateTree(const T* a, size_t size, size_t& index, const T& invilid){Node* root = NULL;if(index<size && a[index] != invilid){root = new Node(a[index]); //创建根节点root->_left = _CreateTree(a, size, ++index, invilid);//递归实现左子树root->_right = _CreateTree(a, size, ++index, invilid);//递归实现右子树}return 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 _PostOrder(Node* root){if(root == NULL){return;}_PostOrder(root->_left);//递归遍历左子树_PostOrder(root->_right);//递归遍历右子树cout<<root->_data<<" ";//打印根节点数据}
层次遍历:
/* 层次遍历:第一层->最后一层 */void _LevelOrder(Node* root){queue<Node*> qt;if(root == NULL){ return;}qt.push(root); //将根节点压到队列中while(!qt.empty()){ /* 当根节点的左孩子不为空,就说明这一层还没有完全压入队列中 */ if(qt.front()->_left != NULL){qt.push(qt.front()->_left); //将根节点左子树压到队列中}/* 当根节点的右孩子不为空,就说明这一层还没有完全压入队列中 */if(qt.front()->_right != NULL){qt.push(qt.front()->_right); //将根节点右子树压到队列中}cout<<qt.front()->_data<<" "; //依次打印节点qt.pop(); //将打印的节点出队列}}
二叉树节点的个数 = 就是左子树节点个数加上右子树节点的个数再加上根节点
size_t _Size(Node* root){if(root == NULL){return 0;}return _Size(root->_left)+_Size(root->_right)+1;//左子树节点+右子树节点+根节点}
二叉树的深度 = 左子树 >= 右子树 ? 左子树+1, 右子树+1;
size_t _Depth(Node* root){if(root == NULL){return 0;}size_t LeftDepth = _Depth(root->_left);size_t RightDepth = _Depth(root->_right);if(LeftDepth >= RightDepth){return LeftDepth+1;}else{return RightDepth+1;}}
二叉树叶子节点的个数 = 左子树的叶子节点 个数+ 右子树的叶子节点个数
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);}
整体代码:
#include <iostream>#include <queue>using namespace std;template <class T>struct BinaryTreeNode{T _data;//数据域BinaryTreeNode<T>* _left;//指向左子树BinaryTreeNode<T>* _right;//指向右子树BinaryTreeNode(const T& d):_data(d),_left(NULL),_right(NULL){}};template<class T>class BinaryTree{typedef BinaryTreeNode<T> Node; //类型重命名,方便后面使用public:BinaryTree():_root(NULL){}BinaryTree(const T* a, size_t size, const T& invilid):_root(NULL){size_t index = 0;_root = _CreateTree(a, size, index, invilid);}BinaryTree<T>(const BinaryTree& tree){_root = _Copy(tree._root);}BinaryTree& operator= (BinaryTree tree) //现代式写法{swap(_root, tree._root);return *this;}~BinaryTree(){if(_root != NULL){_Destroy(_root);}}public: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);}protected: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 LeftDepth = _Depth(root->_left);size_t RightDepth = _Depth(root->_right);if(LeftDepth >= RightDepth){return LeftDepth+1;}else{return RightDepth+1;}}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);}protected:/* 前序遍历:根->左子树->右子树 */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 _PostOrder(Node* root){if(root == NULL){return;}_PostOrder(root->_left);//递归遍历左子树_PostOrder(root->_right);//递归遍历右子树cout<<root->_data<<" ";//打印根节点数据}/* 层次遍历:第一层->最后一层 */void _LevelOrder(Node* root){queue<Node*> qt;if(root == NULL){return;}qt.push(root);while(!qt.empty()){if(qt.front()->_left != NULL){qt.push(qt.front()->_left);}if(qt.front()->_right != NULL){qt.push(qt.front()->_right);}cout<<qt.front()->_data<<" ";qt.pop();}}protected:Node* _Copy(Node* root){if(root == NULL){return NULL;}Node* NewRoot = new Node(root->_data);//创建新的根节点Node* NewCur = NewRoot;NewCur->_left = _Copy(root->_left);NewCur->_right = _Copy(root->_right);return NewRoot;}void _Destroy(Node* root){if(root == NULL){return;}if(root->_left == NULL && root->_right == NULL){delete root;root = NULL;return;}_Destroy(root->_left);_Destroy(root->_right);}Node* _CreateTree(const T* a, size_t size, size_t& index, const T& invilid){Node* root = NULL;if(index<size && a[index] != invilid){ root = new Node(a[index]);//创建根节点 root->_left = _CreateTree(a, size, ++index, invilid);//递归实现左子树 root->_right = _CreateTree(a, size, ++index, invilid);//递归实现右子树}return root;//返回根节点}protected:Node* _root; //根节点};int main(){Test();system("pause");return 0;}
测试结构:
测试代码:
void Test(){int array[10] = {1, 2, 3, '#', '#', 4, '#' , '#', 5, 6};BinaryTree<int> tree(array, 10, '#');tree.PrevOrder();tree.InOrder();tree.PostOrder();tree.LevelOrder();BinaryTree<int> tree2(tree);tree2.PrevOrder();BinaryTree<int> tree3 = tree2;tree3.PrevOrder();}
测试结果:
本文出自 “Pzd流川枫” 博客,请务必保留此出处http://xujiafan.blog.51cto.com/10778767/1765917
0 0
- 树、二叉树基础
- 树 二叉树基础
- 二叉树 基础 笔记
- 二叉树基础使用
- 二叉树基础
- 二叉树系列---基础
- C二叉树基础
- 二叉树基础
- 二叉树基础性质
- 二叉树基础
- /*****/二叉树基础问题
- JavaShowAlgorithm-二叉树基础
- LeetCode基础--二叉树
- 二叉树 基础
- 二叉树基础概念
- 二叉树结构--基础
- 数据结构基础(4)-->二叉树
- 二叉树的基础问题
- C++Primer_笔记_异常处理
- C++_智能指针
- pthread_once,pthread_key_create,pthread_setspecific,pthread_getspecific
- 鸡汤君_一个老程序员的建议66
- 大牛Git教程
- 二叉树基础
- C++ 复杂链表的复制
- 结构体内存对齐
- 二分法查找元素位置
- 防止头文件多次引入
- 理解环境变量
- 部分find命令使用
- Eclipse + Python 的安装与配置流程
- Mysql读写分离,同步复制的探索实现