根节点:根节点是一个没有双亲结点的结点,一课树最多只能有一个根节点
结点:树上面的所有数据都是结点,但结点不只包括数据,还包含指向子树的分支
结点的度:结点拥有子树或分支的个数
树的度:树中各结点的最大值
结点的层数:根结点的层数为0,其他结点的层数等于其父结点的层数加1
树的深度:树中所有结点层数的最大值
树的高度:数的深度加1
叶子结点:没有孩子结点的结点
A
B C
D E F G
H I
树的前序遍历操作定义为:
访问根结点
按照从左到右的顺序前序遍历根结点的每一棵子树。
A B D E H I F C G
树的后序遍历操作定义为:
按照从左到右的顺序后序遍历根结点的每一棵子树
访问根结点。
D H I E F B G C A
树的层序遍历操作定义为:
从树的第一层(即根结点)开始,自上而下逐层遍历,在同一层中,按从左到右的顺序对结点逐个访问。
A B C D E F G H I
二叉树的遍历:
A
B C
D E F
G
前序遍历
访问根结点
前序遍历根结点的左子树
前序遍历根结点的右子树。
A B D G C E F
中序(根)遍历
中序遍历根结点的左子树
访问根结点
中序遍历根结点的右子树。
D G B A E C F
后序(根)遍历
后序遍历根结点的左子树
后序遍历根结点的右子树
访问根结点;
G D B E F C A
层序遍历
二叉树的层次遍历是指从二叉树的第一层开始,
从上至下逐层遍历,在同一层中,则按从左到右的顺序对结点逐个访问。
A B C D E F G
二叉树的顺序存储
以结点在完全二叉树中的位置层序遍历编号,按编号存入线性表
void create(char preorder[],char inorder[],int start_p, int end_p,int start_i,int end_i, char data[],int root){
if(start_p>end_p)
return ;
else{
int k;
for(int i=start_i;i<=end_i;i++){
if(inorder[i]==preorder[start_p]){
k=i;
break;
}
}
data[root]=preorder[start_p];
create(preorder,inorder,start_p+1,start_p+k-start_i,start_i,k-1,data, 2*root);
create(preorder,inorder,start_p+k-start_i+1,end_p,k+1,end_i,data,2*root+1);
}
return ;
}
int main(){
char * data;
int total=1;
char preorder[100],inorder[100];
cin>>preorder>>inorder;
int length=0;
while(preorder[length]!='\0')
length++;
data=new char[pow(2,length+1)];
memset(data,'\0',pow(2,length+1));
create(preorder,inorder,0,length-1,0,length-1,data,1);
order(1,data);
return 0;
}
二叉链表
结点结构
lchild data rchild
左孩子 数据 右孩子
template <class T>
struct node
{
T data;
BiNode<T> *lchild, *rchild;
};
类的声明
template <class T>
class BiTree
{
public:
BiTree();
~BiTree( );
void PreOrder(){PreOrder(root);}
void InOrder() {InOrder(root);}
void PostOrder() {PostOrder(root);}
void LevelOrder(){LeverOrder(root)};
private:
BiNode<T> *root;
BiNode<T> * Creat( );
void Release(BiNode<T> *root);
void PreOrder(BiNode<T> *root);
void InOrder(BiNode<T> *root);
void PostOrder(BiNode<T> *root);
void LevelOrder(BiNode<T> *root);
};
前序遍历(递归)
template <class T>
void BiTree::PreOrder(BiNode<T> *root)
{
if (root ==NULL) return;
else {
cout<<root->data;
PreOrder(root->lchild);
PreOrder(root->rchild);
}
}
template <class T>
void BiTree::PreOrder(BiNode<T> *root) {
if (root ==NULL) return;
else {
cout<<root->data;
PreOrder(root->lchild);
PreOrder(root->rchild);
}
}
template <class T>
void BiTree::PreOrder(BiNode<T> *root) {
if (root ==NULL) return;
else {
cout<<root->data;
PreOrder(root->lchild);
PreOrder(root->rchild);
}
}
template <class T>
void BiTree::PreOrder(BiNode<T> *root) {
if (root ==NULL) return;
else {
cout<<root->data;
PreOrder(root->lchild);
PreOrder(root->rchild);
}
}
中序遍历(递归)
template <class T>
class BiTree{
public:
BiTree();
~BiTree( );
void PreOrder(){PreOrder(root);}
void InOrder() {InOrder(root);}
void PostOrder() {PostOrder(root);}
void LevelOrder();
private:
BiNode<T> *root;
void Creat(BiNode<T> *& root);
void Release(BiNode<T> *root);
void PreOrder(BiNode<T> *root);
void InOrder(BiNode<T> *root);
void PostOrder(BiNode<T> *root);
void LevelOrder(BiNode<T> *root);
};
template <class T>
void BiTree<T>::Creat(BiNode<T> * &root )
{
T ch;
cout<<"请输入创建一棵二叉树的结点数据"<<endl;
cin>>ch;
if (ch=="#") root = NULL;
else{
root = new BiNode<T>; //生成一个结点
root->data=ch;
Creat(root->lchild ); //递归建立左子树
Creat(root->rchild); //递归建立右子树
}
}
统计叶子节点的数目
增加一个数据成员,leafcount, 初值为0
对树进行遍历。 如果一个节点是叶子,则将leafcount+1;
可以在前序、中序或后序的遍历过程中进行计算。
算法分析
从根节点出发
判断当前节点是否是叶子节点,如果是,则叶子数+1
否则,在左子树中遍历,并统计叶子节点的数目,在右子树中进行遍历,并统计叶子节点的数目
template<typename T>
void BiTree<T>:: countleaf(BiTreeNode<T> * root){
if (root) {
if (root->lchild==NULL && root->rchild==NULL)
leafcount=leafcount+1;
else
{
countleaf(root->lchild);
countleaf(root->rchild);
}
}
return;
}