二叉树基础

来源:互联网 发布:淘宝如何自动发卡密 编辑:程序博客网 时间:2024/05/16 14:04

二叉树:二叉树是一棵特殊的树,二叉树每个节点最多有两个孩子结点,分别称为左孩子和右孩子。

二叉树节点结构:

        wKiom1cXSA-R8FzsAAAU8gpgpSo969.png

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;}

测试结构:

wKiom1cXUKiwnSr4AAAUJz7J3rI335.png

测试代码:

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();}

测试结果:

wKiom1cXUOfieZY0AAAdHNO_XQI909.png

本文出自 “Pzd流川枫” 博客,请务必保留此出处http://xujiafan.blog.51cto.com/10778767/1765917

0 0
原创粉丝点击