树:
n个结点的有限集合,当n等于0时为空树。
任意一棵非空树满足以下条件:
⑴ 有且仅有一个特定的称为根的结点;
⑵ 当n>1时,除根结点之外的其余结点被分成m(m>0)个互不相交的有限集合T1,T2,… ,Tm,其中每个集合又是一棵树,并称为这个根结点的子树。
树的定义采用递归方法。
结点的度:结点所拥有子树的个数
树的度:树中各结点度的最大值
叶子结点:度为0的结点
分支节点:度不为零的结点
结点所在层数:根结点的层数为1;对其余任何结点,若某结点在第k层,则其孩子结点在第k+1层。
树的深度:树中所有结点的最大层数,也称高度
重点:二叉树:
二叉树是n(n≥0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成。
二叉树的结点度数最大为2,二叉树是有序的。
特殊的二叉树:满二叉树
在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上。
特点:叶子只能出现在最下层,只有度为0和度为2的结点。
满二叉树在同样深度的二叉树中结点个数最多
满二叉树在同样深度的二叉树中叶子结点个
完全二叉树:
在满二叉树中,从最后一个结点开始,连续去掉任意个结点,即是一棵完全二叉树。
特点:1:叶子结点只能出现在最下两层,且最下层的叶子结点都集中在二叉树的左部;
2. 完全二叉树中如果有度为1的结点,只可能有一个,且该结点只有左孩子。
3. 深度为k的完全二叉树在k-1层上一定是满二叉树。
二叉树的基本性质
1:二叉树的第i层上最多有2i-1个结点(i≥1)
2:一棵深度为k的二叉树中,最多有2k-1个结点,最少有k个结点。
3:在一棵二叉树中,如果叶子结点数为n0,度为2的结点数为n2,则有: n0=n2+1.
结点总数:N=n0+n1+n2,树枝数B=N-1,B=n1+2*n2.
4:具有n个结点的完全二叉树的深度为 [log2n] (向下取整) +1。
对一棵具有n个结点的完全二叉树中从1开始按层序编号,则
结点i的双亲结点为 i/2;
结点i的左孩子为2i;
结点i的右孩子为2i+1。
== 二叉树的遍历操纵:==
前序遍历
若二叉树为空,则空操作返回;否则:
①访问根结点;
②前序遍历根结点的左子树;
③前序遍历根结点的右子树。
中序遍历
若二叉树为空,则空操作返回;否则:
①中序遍历根结点的左子树;
②访问根结点;
③中序遍历根结点的右子树。
后序遍历
若二叉树为空,则空操作返回;否则:
①后序遍历根结点的左子树;
②后序遍历根结点的右子树。
③访问根结点;
层序遍历
二叉树的层次遍历是指从二叉树的第一层(即根结点)开始,从上至下逐层遍历,在同一层中,则按从左到右的顺序对结点逐个访问。
二叉树的顺序存储:
二叉树的顺序存储结构就是用一维数组存储二叉树中的结点,并且结点的存储位置(下标)应能体现结点之间的逻辑关系——父子关系。
完全二叉树和满二叉树中结点的序号可以唯一地反映出结点之间的逻辑关系。
二叉树的顺序存储:
按照完全二叉树编号,然后以编号为数组下标进行存储,如果改编号下没有元素,则存储 ‘\0’。 这样就能体现结点之间的父子关系。
知道二叉树的前序遍历和中序遍历可以确定一个二叉树
用递归方法来实现前序遍历:
void Preorder(int root, char data[])
{
if(data[root]!=’\0’){
cout<<data[root] ;
Preorder(2root,data);
Preorder(2root+1,data); }
return ;}
中序遍历
void InOrder(int root, char data[]){
if(data[root]!=’\0’){
InOrder(2root,data);
cout<<data[root] ;
InOrder(2root+1,data);
}
return;
}
后序遍历:
void PostOrder(int root, char data[]){
if(data[root]!=’\0’){
PostOrder(2root,data);
PostOrder(2root+1,data);
cout<<data[root] ;
}
return;
}
链式二叉树
template
struct BiNode
{
T data;
BiNode *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) {
SeqStack<BiNode<T> *> s;
while (root!=NULL | | !s.empty()) {
while (root!= NULL) {
cout<<root->data;
s.push(root);
root=root->lchild;
}
if (!s.empty()) {
root=s.pop();
root=root->rchild;
}
}
}
中序遍历-递归算法
template <class T>
void BiTree::InOrder (BiNode<T> *root)
{
if (root==NULL) return;
else {
InOrder(root->lchild);
cout<<root->data;
InOrder(root->rchild);
}
}
中序遍历-非递归算法-用栈来实现
template <class T>
void BiTree::InOrderwithoutD (BiNode<T> *root)
{
stack< BiNode<T> * > aStack;
while(!aStack.empty()||root) {
while(root){
aStack.push(root);
root=root->lchild;
}
if(!aStack.empty()){
root=aStack.top();
aStack.pop();
cout<<root->data;
root=root->rchild;
}
}
}
二叉树的创建
template<class T>
BiTree<T>::BiTree( )
{
Creat(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); //递归建立右子树
}
}
后序遍历-递归算法
template <class T>
void BiTree::PostOrder(BiNode<T> *root)
{
if (root==NULL) return;
else {
PostOrder(root->lchild);
PostOrder(root->rchild);
cout<<root->data;
}
}
后序遍历-非递归算法
void tree::T_print(BiNode<T> *bt){
stack<BiNode<T>*> s;
BiNode<T> *cur, *pre=NULL;
if (root==NULL) return;
s.push(bt);
while (!s.empty()) {
cur=s.top();
if ((cur->Lchild==NULL&&cur->Rchild==NULL) ||(pre!=NULL&&(pre==cur->Lchild||pre==cur->Rchild)))
{
cout<<cur->data; s.pop(); pre=cur;
}
else
{
if (cur->Rchild!=NULL) s.push(cur->Rchild);
if (cur->Lchild!=NULL) s.push(cur->Lchild);
}
}
}
层序遍历-用队列来实现
template<class T>
void BiTree<T>::LevelOrder(BiNode<T>* root){
queue<BiNode<T>*> aQueue;
if(root)
aQueue.push(root);
while(!aQueue.empty())
{
root=aQueue.front(); //取队列首结点
aQueue.pop();
cout<<pointer->data;//访问当前结点
if(root->lchild) //左子树进队列
aQueue.push(root->lchild);
if(root->rchild) //右子树进队列
aQueue.push(root->rchild);
}//end while
}
二叉树的析构
template<class T>
void BiTree<T>::Release(BiNode<T>* root){
if (root != NULL){
Release(root->lchild); //释放左子树
Release(root->rchild); //释放右子树
delete root;
}
}
template<class T>
BiTree<T>::~BiTree(void)
{
Release(root);
}