二叉树的定义:一颗二叉树是一个结点集合。这个集合要么为空,要么满足以下条件:
- 它仅有一个被称为根的结点。
- 除了根结点,其他结点可以被分为两个不相交的子集T1和T2,它们也是二叉树,分别叫做根的左子树和右子数。
满二叉树定义:一颗深度为K且有2**k-1个结点的二叉树称为满二叉树。
完全二叉树定义:一颗深度为k的完全二叉树满足以下两点:
- 叶子结点只可能在层次最大的两层上出现
- 对任一结点,若其右分支下的子孙的最大层次为L,则其左分支下的子孙的最大层次必为L或L+1
完全二叉树的判断
叶子节点:二叉树汇总所有度为0的结点都称为叶子结点或终端结点
二叉树的遍历:访问二叉树中所有结点,每个结点能且只能访问依次。包括前序遍历,中序遍历和后序遍历。
前序遍历顺序:
- 访问根结点
- 前序遍历根结点的左子树
- 前序遍历根结点的右子数
遍历示意图
前序遍历算法实现 实现代码来自王治和教授数据结构课堂的总结
template <class T>
void Binary_tree<T>::recursive_preorder(Binary_node<T> *sub_root)
{ if (sub_root==NULL)
return;
cout<<sub_root->data<<" ";
recursive_preorder(sub_root->left);
recursive_preorder(sub_root->right);
};
中序遍历顺序:
- 中序遍历根结点的左子树
- 访问根结点
- 中序遍历根结点的右子数
遍历示意图
中序遍历算法实现
template <class T>
void Binary_tree<T>::recursive_inorder(Binary_node<T> *sub_root)
{ if (sub_root==NULL)
return;
recursive_inorder(sub_root->left);
cout<<sub_root->data<<" ";
recursive_inorder(sub_root->right);
};
后序遍历顺序:
- 后序遍历根结点的左子树
- 后序遍历根结点的右子数
- 访问根结点
遍历示意图
后序遍历算法实现
template <class T>
void Binary_tree<T>::recursive_postorder(Binary_node<T> *sub_root)
{ if (sub_root==NULL)
return;
recursive_postorder(sub_root->left);
recursive_postorder(sub_root->right);
cout<<sub_root->data<<" ";
};
二叉树的存储:使用二叉链表结构存储二叉树
二叉链表结构的算法实现:
template <class T>
struct Binary_node{
T data;
Binary_node<T> *left;
Binary_node<T> *right;
Binary_node(){
left=right=NULL;
}
Binary_node(T item,Binary_node<T> *lptr=NULL,Binary_node<T> *rptr=NULL){
data=item;
left=lptr;
right=rptr;
}
};
二叉树高度计算算法实现
template <class T>
int Binary_tree<T>::recursive_height(Binary_node<T> *sub_root)
{ int l,r,h;
if (sub_root==NULL)
return 0;
l=recursive_height(sub_root->left);
r=recursive_height(sub_root->right);
h=1+(l>r?l:r);
return h;
};
二叉树结点计算算法实现
template <class T>
void Binary_tree<T>::recursive_size(Binary_node<T> *sub_root,int &num)
{ if (sub_root==NULL)
return;
num++;
recursive_size(sub_root->left,num);
recursive_size(sub_root->right,num);
};
二叉树测试代码如下:
- 二叉树功能实现类
#include <iostream>
using namespace std;
template <class T>
struct Binary_node{
T data;
Binary_node<T> *left;
Binary_node<T> *right;
Binary_node(){
left=right=NULL;
}
Binary_node(T item,Binary_node<T> *lptr=NULL,Binary_node<T> *rptr=NULL){
data=item;
left=lptr;
right=rptr;
}
};
template <class T>
class Binary_tree
{ protected:
Binary_node<T> *root;
int number;
public:
Binary_tree()
{ root=NULL; }
void create_tree();
void preorder()
{ recursive_preorder(root);
}
void inorder()
{ recursive_inorder(root);
}
void postorder()
{ recursive_postorder(root);
}
int size()
{
recursive_size(root,number);
return number;
}
int height()
{ return recursive_height(root);
}
private:
void recursive_preorder(Binary_node<T> *sub_root);
void recursive_inorder(Binary_node<T> *sub_root);
void recursive_postorder(Binary_node<T> *sub_root);
void recursive_size(Binary_node<T> *sub_root,int &num);
int recursive_height(Binary_node<T> *sub_root);
};
// Create a binary tree X(Y(NULL,NULL),A(B(NULL,D(NULL,NULL)),C(E(NULL,NULL),NULL)))
template <class T>
void Binary_tree<T>::create_tree()
{ Binary_node<T> *xn,*yn,*an,*bn,*cn,*dn,*en;
dn=new Binary_node<T>('D');
en=new Binary_node<T>('E');
bn=new Binary_node<T>('B',NULL,dn);
cn=new Binary_node<T>('C',en,NULL);
an=new Binary_node<T>('A',bn,cn);
yn=new Binary_node<T>('Y');
root=xn=new Binary_node<T>('X',yn,an);
}
template <class T>
void Binary_tree<T>::recursive_preorder(Binary_node<T> *sub_root)
{ if (sub_root==NULL)
return;
cout<<sub_root->data<<" ";
recursive_preorder(sub_root->left);
recursive_preorder(sub_root->right);
};
template <class T>
void Binary_tree<T>::recursive_inorder(Binary_node<T> *sub_root)
{ if (sub_root==NULL)
return;
recursive_inorder(sub_root->left);
cout<<sub_root->data<<" ";
recursive_inorder(sub_root->right);
};
template <class T>
void Binary_tree<T>::recursive_postorder(Binary_node<T> *sub_root)
{ if (sub_root==NULL)
return;
recursive_postorder(sub_root->left);
recursive_postorder(sub_root->right);
cout<<sub_root->data<<" ";
};
template <class T>
void Binary_tree<T>::recursive_size(Binary_node<T> *sub_root,int &num)
{ if (sub_root==NULL)
return;
num++;
recursive_size(sub_root->left,num);
recursive_size(sub_root->right,num);
};
template <class T>
int Binary_tree<T>::recursive_height(Binary_node<T> *sub_root)
{ int l,r,h;
if (sub_root==NULL)
return 0;
l=recursive_height(sub_root->left);
r=recursive_height(sub_root->right);
h=1+(l>r?l:r);
return h;
};
- 功能实现测试类
#include <iostream>
#include "binary_tree.cpp"
int number=0;
int main()
{ Binary_tree<char> btree;
cout<<"二叉树是: X(Y(NULL,NULL),A(B(NULL,D(NULL,NULL)),C(E(NULL,NULL),NULL)))"<<endl<<endl;
btree.create_tree();
cout<<"前序遍历结果是:";
btree.preorder();
cout<<endl;
cout<<"中序遍历结果是:";
btree.inorder();
cout<<endl;
cout<<"后序遍历结果是:";
btree.postorder();
cout<<endl;
cout<<"结点个数是:";
cout<<btree.size()<<endl;
cout<<"高度是:";
cout<<btree.height()<<endl;
return 0;
}
- 测试截图