树的基本概念:ios
树是n(n>=0)个有限个数据的元素集合,形状像一颗倒过来的树。数组
结点:结点包含数据和指向其它结点的指针。ide
根节点:树第一个结点称为根节点。函数
结点的度:结点拥有的子节点个数。this
叶节点:没有子节点的节点(度为0)。spa
父子节点:一个节点father指向另外一个节点child,则child为孩子节点,father为父亲结点。3d
兄弟节点:具有相同父节点的节点互为兄弟节点。指针
节点的祖先:从根节点开始到该节点所经的全部节点均可以称为该节点的祖先。orm
子孙:以某节点为根的子树中任一节点都称为该节点的子孙。blog
树的高度:树中距离根节点最远结点的路径长度。
二叉树的概念:
二叉树是一棵特殊的树,二叉树每一个节点最多有两个孩子结点,分别称为左孩子和右孩子。
二叉树的存储方式:
(1)数组存储方式 即用一组连续的存储单元存储二叉树的数据元素。
例如:
(2)链式存储方式
这里咱们主要讨论每一个结点包含三个域的状况
二叉树的结点的结构
template<class T>
struct BinaryTreeNode
{
BinaryTreeNode(const T& x) //构造函数
:_data(x)
,_left(NULL)
,_right(NULL)
{ }
T _data; //结点的值
BinaryTreeNode<T>* _left; //指向左子树的结点
BinaryTreeNode<T>* _right; //指向右子树的结点
};
部分代码以下:
二叉树的遍历(前序、中序、后序、层次)
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 _PosOrder(Node* root) //后序遍历打印二叉树
{
if(root == NULL)
return;
_PosOrder(root->_left);
_PosOrder(root->_right);
cout<<root->_data<<" ";
}
void _LevelOrder(Node* root) //层次遍历
{
queue<Node*> p;
if(root == NULL)
{
return;
}
p.push(root);
while (!p.empty())
{
if(p.front()->_left != NULL)
{
p.push(p.front()->_left);
}
if(p.front()->_right != NULL)
{
p.push(p.front()->_right);
}
cout<<p.front()->_data<<" ";
p.pop();
}
}
二叉树中结点的个数
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);
return leftdepth > rightdepth ? leftdepth + 1 : 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);
}
二叉树的镜像(即交换二叉树每个结点的左右子结点)
void _MirrorRecursively(Node* root)//二叉树的镜像
{
//判断根节点及左右子树是否为空
if(root == NULL || (root->_left == NULL && root->_right == NULL))
return;
Node* temp = root->_left; //交换左右子节点
root->_left = root->_right;
root->_right = temp;
if(root->_left != NULL)
_MirrorRecursively(root->_left);
if(root->_right != NULL)
_MirrorRecursively(root->_right);
}
判断子树问题
bool HasSubtree(Node* root2)//判断root2是不是_root的子树
{
bool result = false;
if(_root != NULL && root2 != NULL)
{
if(_root->_data == root2->_data)
{
result = DoseTree1HaveTree2(_root,root2);
}
if(!result)
result = HasSubtree(_root->_left,root2);
if(!result)
result = HasSubtree(_root->_right,root2);
}
return result;
}
bool DoseTree1HaveTree2(Node* root2)//判断在tree1中是否有以tree2根节点的左右子树结构
{
if(root2 == NULL)
return true;
if(_root == NULL)
return false;
if(_root->_data != root2->_data)
return false;
return DoseTree1HaveTree2(_root->_left,root2->_left) && DoseTree1HaveTree2(_root->_right,root2->_right);
}
以上只是部分代码,具体源代码以下:
#pragma once
#include<iostream>
#include<queue>
using namespace std;
//二叉树中结点的结构
template<class T>
struct BinaryTreeNode
{
BinaryTreeNode(const T& x) //构造函数
:_data(x)
,_left(NULL)
,_right(NULL)
{ }
T _data; //结点的值
BinaryTreeNode<T>* _left; //指向左子树的结点
BinaryTreeNode<T>* _right; //指向右子树的结点
};
template<class T>
class BinaryTree
{
typedef BinaryTreeNode<T> Node;//简化命名
public:
BinaryTree() //默认构造函数
:_root(NULL)
{ }
BinaryTree(const T* a,size_t size,const T& invalid) //构造函数
:_root(NULL)
{
size_t index = 0;
_root = _CreateTree(a,size,invalid,index); //建立一个二叉树
}
BinaryTree(const BinaryTree<T>& t) //拷贝构造函数
:_root(NULL)
{
_Copy(t._root);
}
BinaryTree<T>& operator=(const BinaryTree<T>& t) //赋值函数
{
if(this != &t)
{
_Destroy(t._root);
_Copy(t._root);
}
return *this;
}
~BinaryTree() //析构函数
{
if(_root)
{
_Destroy(_root);
}
}
void PrevOrder() //前序遍历打印二叉树
{
cout<<"前序遍历:";
_PrevOrder(_root);
cout<<endl;
}
void InOrder()//中序遍历打印二叉树
{
cout<<"中序遍历:";
_InOrder(_root);
cout<<endl;
}
void PosOrder()//后续序遍历打印二叉树
{
cout<<"后序遍历:";
_PosOrder(_root);
cout<<endl;
}
void LevelOrder() //层次遍历
{
cout<<"层次遍历:";
_LevelOrder(_root);
cout<<endl;
}
size_t Size() //求结点的个数
{
return _Size(_root);
}
size_t Depth()//树的深度
{
return _Depth(_root);
}
size_t LeafSize() //叶子节点个数
{
return _LeafSize(_root);
}
bool HasSubtree(Node* root2)//判断root2是不是_root的子树
{
bool result = false;
if(_root != NULL && root2 != NULL)
{
if(_root->_data == root2->_data)
{
result = DoseTree1HaveTree2(_root,root2);
}
if(!result)
result = HasSubtree(_root->_left,root2);
if(!result)
result = HasSubtree(_root->_right,root2);
}
return result;
}
void MirrorRecursively()//二叉树的镜像
{
_MirrorRecursively(_root);
}
protected:
Node* _CreateTree(const T* a,size_t size,const T& invalid,size_t& index) //建立一个二叉树
{
Node* root = NULL;
if(a[index] != invalid && index < size)
{
root = new Node(a[index]);
root->_left = _CreateTree(a,size,invalid,++index);
root->_right = _CreateTree(a,size,invalid,++index);
}
return root;
}
void _Copy(Node* sroot)//拷贝函数
{
Node* root = NULL;
if(sroot == nul) //判断根节点
return;
if(sroot->_left && sroot->_right) //判断根节点的左右子树
{
root = new Node(sroot->_data);
return ;
}
root->_left = _Copy(sroot->_left);//依次拷贝左子树
root->_right = _Copy(sroot->_right);//依次拷贝右子树
}
void _Destroy(Node* root)//销毁二叉树
{
if(root == NULL)
{
return;
}
if(root->_left && root->_right)
{
delete root;
root = NULL;
return;
}
_Destroy(root->_left);
_Destroy(root->_right);
}
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 _PosOrder(Node* root) //后序遍历打印二叉树
{
if(root == NULL)
return;
_PosOrder(root->_left);
_PosOrder(root->_right);
cout<<root->_data<<" ";
}
void _LevelOrder(Node* root) //层次遍历
{
queue<Node*> p;
if(root == NULL)
{
return;
}
p.push(root);
while (!p.empty())
{
if(p.front()->_left != NULL)
{
p.push(p.front()->_left);
}
if(p.front()->_right != NULL)
{
p.push(p.front()->_right);
}
cout<<p.front()->_data<<" ";
p.pop();
}
}
void _MirrorRecursively(Node* root)//二叉树的镜像
{
//判断根节点及左右子树是否为空
if(root == NULL || (root->_left == NULL && root->_right == NULL))
return;
Node* temp = root->_left; //交换左右子节点
root->_left = root->_right;
root->_right = temp;
if(root->_left != NULL)
_MirrorRecursively(root->_left);
if(root->_right != NULL)
_MirrorRecursively(root->_right);
}
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);
return leftdepth > rightdepth ? leftdepth + 1 : 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);
}
bool DoseTree1HaveTree2(Node* root2)//判断在tree1中是否有以tree2根节点的左右子树结构
{
if(root2 == NULL)
return true;
if(_root == NULL)
return false;
if(_root->_data != root2->_data)
return false;
return DoseTree1HaveTree2(_root->_left,root2->_left) && DoseTree1HaveTree2(_root->_right,root2->_right);
}
protected:
Node* _root;//根节点
};
void Test()
{
int a1[10] = {1,2,3,'#','#',4,'#','#',5,6};
int a2[15] = {1,2,'#',3,'#','#',4,5,'#',6,'#',7,'#','#',8,};
int a3[5] = {2,3,'#','#',4};
BinaryTree<int> t1(a1,10,'#');
BinaryTree<int> t2(a2,15,'#');
BinaryTree<int> t3(a3,5,'#');
cout<<"t1遍历二叉树(前序,中序,后序,层次):"<<endl;
t1.PrevOrder();
t1.InOrder();
t1.PosOrder();
t1.LevelOrder();
cout<<"二叉树结点的个数:"<<t1.Size()<<endl;
cout<<"二叉树的深度:"<<t1.Depth()<<endl;
cout<<"二叉树的叶子节点数:"<<t1.LeafSize()<<endl;
cout<<"二叉树的镜像:"<<endl;
t1.MirrorRecursively();
t1.PrevOrder();
cout<<endl;
cout<<"t2遍历二叉树(前序,中序,后序,层次):"<<endl;
t2.PrevOrder();
t2.InOrder();
t2.PosOrder();
t2.LevelOrder();
cout<<"二叉树结点的个数:"<<t2.Size()<<endl;
cout<<"二叉树的深度:"<<t2.Depth()<<endl;
cout<<"二叉树的叶子节点数:"<<t2.LeafSize()<<endl;
cout<<"二叉树的镜像:"<<endl;
t2.MirrorRecursively();
t2.PrevOrder();
cout<<endl;
}