引言: 因为最近准备期末,所以进度有些慢。现在我们就进入数据结构与算法——树的学习,主要是二叉树的学习。
一.树的定义
定义:树是n(n>=0)个节点的有限集合。n=0时称为空树。在任意一个非空树中:
(1):有且仅有一个特定的根节点;
(2):当n>1时,其余节点可为m(m>0)个互不相交的有限集,称为子树。
——借鉴与《大话数据结构》
二.二叉树
1.二叉树的定义
定义:二叉树是n(n>=0)个节点的有限集合,该集合或者为空集,或者有一个根节点和两棵互不相交的左右子树组成。
2.二叉树的基本形态
一共有五种:
(1)空二叉树
(2)只有一个根节点
(3)根节点只有左子树
(4)根节点只有右子树
(5)根节点既有左子树又有右子树
3.特殊二叉树
(1)斜树:只有左子树或者右子树。
(2)满二叉树:在一棵二叉树中,如果所有节点都存在左子树与右子树,并且所有叶子结点都在同一层上,为满二叉树。
(3)完全二叉树:对一棵树按层编号,如果编号为i的节点与同样深度的满二叉树中编号为i的节点在二叉树中位置完全相同,则为完全二叉树。
——见与《大话数据结构》
4.二叉树的性质
性质一:在二叉树的第i层至多有2^(i-1)个节点。
性质二:深度为K的二叉树至多有2^k-1个节点。
性质三:对于任意一棵二叉树T,如果其终端节点数为N0,度为2的节点数为N2,则N0=N2+1.
性质四:具有n个结点的二叉树,深度为不大于(logn/log2)的最大整数 + 1。
性质五:有n个结点的完全二叉树,从上往下从左往右编号为i,则不大于i/2的最大整数位该结点的双亲结点,2i为该结点的左孩子结点,2i+1位该结点的右孩子节点。
三.二叉树的创建与遍历
定义式
struct Tree
{
char data;//数据域
struct Tree *rchild,*lchild;//左右孩子指针
};
在二叉树中有四种遍历方式,分别是前序遍历,中序遍历,后序遍历,层次遍历。这里给出前三种。
前序遍历:
void front(struct Tree* &q)
{
if(q)
{
cout<<q->data;
front(q->lchild);
front(q->rchild);
}
}
中序遍历:
void middle(struct Tree* &q)
{
if(q)
{
middle(q->lchild);
cout<<q->data;
middle(q->rchild);
}
}
后序遍历:
void end(struct Tree* &q)
{
if(q)
{
end(q->lchild);
end(q->rchild);
cout<<q->data;
}
}
创立二叉树
void creat(struct Tree* &p)
{
char s;
cin>>s;
if(s=='#')
p=NULL;
else
{
p=new(struct Tree);
p->data=s;
creat(p->lchild);
creat(p->rchild);
}
}
完整代码
#include <iostream>
using namespace std;
struct Tree
{
char data;
struct Tree *rchild,*lchild;
};
void creat(struct Tree* &p)
{
char s;
cin>>s;
if(s=='#')
p=NULL;
else
{
p=new(struct Tree);
p->data=s;
creat(p->lchild);
creat(p->rchild);
}
}
void front(struct Tree* &q)
{
if(q)
{
cout<<q->data;
front(q->lchild);
front(q->rchild);
}
}
void middle(struct Tree* &q)
{
if(q)
{
middle(q->lchild);
cout<<q->data;
middle(q->rchild);
}
}
void end(struct Tree* &q)
{
if(q)
{
end(q->lchild);
end(q->rchild);
cout<<q->data;
}
}
int main()
{
struct Tree *tree;
creat(tree);//创建二叉树
front(tree);//前序遍历
cout<<endl;
middle(tree);//中序遍历
cout<<endl;
end(tree);//后序遍历
return 0;
}
四.后记
树的知识是非常丰富的,比如森林与树的关系等等。但是我们应该先了解树的基本操作,在进行下一步的学习。下一次将是数据结构与算法——图的学习。