读书笔记之:数据结构,算法与应用(3)

第8章 二叉树和其他树
1. 术语:
树和二叉树的术语,如高度、深度、层、根、叶子、子节点、父节点和兄弟节点。
4种常用的二叉树遍历方法:前序遍历,中序遍历,后序遍历和按层遍历。
2. 线性数据结构,表数据结构,层次数据结构
3. 二叉树与树的根本区别
4. 二叉树的特性
5. 二叉树遍历方法
在前三种方法中,每个节点的左子树在其右子树之前遍历。这三种遍历的区别在于对同一个节点在不同时刻进行访问。在进行前序遍历时,每个节点是在其左右子树被访问之前进行访问的;在中序遍历时,首先访问左子树,然后访问子树的根节点,最后访问右子树。在后序遍历时,当左右子树均访问完之后才访问子树的根节点。
在逐层遍历过程中,按从顶层到底层的次序访问树中元素,在同一层中,从左到右进行访问。由于遍历中所使用的数据结构是一个队列而不是栈,因此写一个按层遍历的递归程序很困难。
6. 二叉树遍历一个常用问题:数学表达式的形式
当对一棵数学表达式树进行中序,前序和后序遍历时,就分别得到表达式的中缀、前缀和后缀形式。中缀( infix)形式即平时所书写的数学表达式形式,在这种形式中,每个二元操作符(也就是有两个操作数的操作符)出现在左操作数之后,右操作数之前。在使用中缀形式时,可能会产生一些歧义。例如, x+y×z 可以理解为 (x+y)×z 或x+(y×z)。为了避免这种歧义,可
对操作符赋于优先级并采用优先级规则来分析中缀表达式。在完全括号化的中缀表达式中,每个操作符和相应的操作数都用一对括号括起来。更甚者把操作符的每个操作数也都用一对括号括起来。如 ((x)+(y)),((x)+((y)*(z)))和(((x)+(y))*((y)+(z)))*(w)。
在后缀(postfix)表达式中,每个操作符跟在操作数之后,操作数按从左到右的顺序出现。在前缀( p r e f i x)表达式中,操作符位于操作数之前。在前缀和后缀表达式中不会存在歧义。因此,在前缀和后缀表达式中都不必采用括号或优先级。从左到右或从右到左扫描表达式并采用操作数栈,可以很容易确定操作数和操作符的关系。若在扫描中遇到一个操作数,把它压入堆栈,若遇到一个操作符,则将其与栈顶的操作数相匹配。把这些操作数推出栈,由操作符执行相应的计算,并将所得结果作为操作数压入堆栈。
7. 抽象数据结构:二叉树
 

二叉树节点代码:

View Code
#ifndef _BINARYTREENODE_H_
#define _BINARYTREENODE_H_
template < class T>
class BinaryTree;
class Booster;
template < class T>
class BinaryTreeNode{
    friend  class BinaryTree<T>;
    friend  class Booster;
    friend  void PlaceBoosters(BinaryTreeNode<Booster>*);
     public:
    BinaryTreeNode(){
        lchild=rchild= 0;
    }
    BinaryTreeNode( const T& e){
        data=e;
        lchild=rchild= 0;
    }
    BinaryTreeNode( const T& e,BinaryTreeNode<T>* l,BinaryTreeNode<T>* r){
        data=e;
        lchild=l;
        rchild=r;
    }
    T getData(){
         return data;
    }
    BinaryTreeNode<T>* getLChild(){
         return lchild;
    }
    BinaryTreeNode<T>* getRChild(){
         return rchild;
    }
     void setData( const T& e){
        data=e;
    }
     void setLChild(BinaryTreeNode<T>* l){
        lchild=l;
    }
     void setRChild(BinaryTreeNode<T>* r){
        rchild=r;
    }
     private:
    T data;
    BinaryTreeNode<T> *lchild;
    BinaryTreeNode<T> *rchild;
};
#endif

数据类型二叉树类:

View Code
#ifndef _BINARYTREE_H_
#define _BINARYTREE_H_
#include <iostream>
#include <queue>
#include  " BinaryTreeNode.h "
int _count;
template < class T>
class BinaryTree{
     public:
        BinaryTree():root( 0){}
        ~BinaryTree(){}
         bool IsEmpty() const{
             return root? false: true;
        }
         bool Root(T& x) const;
         void MakeTree( const T& elem,BinaryTree<T>& left,BinaryTree<T>& right);
         void BreakTree(T& elem,BinaryTree<T>& left,BinaryTree<T>& right);
         void PreOrder( void(*Visit)(BinaryTreeNode<T>* u)){
            PreOrder(Visit,root);
        }
         void InOrder( void(*Visit)(BinaryTreeNode<T>* u)){
            InOrder(Visit,root);
        }
         void PostOrder( void(*Visit)(BinaryTreeNode<T>* u)){
            PostOrder(Visit,root);
        }
         void LevelOrder( void(*Visit)(BinaryTreeNode<T>*u));
         void PreOutput(){
            PreOrder(Output,root);
            std::cout<<std::endl;
        }
         void InOutput(){
            InOrder(Output,root);
            std::cout<<std::endl;
        }
         void PostOutput(){
            PostOrder(Output,root);
            std::cout<<std::endl;
        }
         void LevelOutput(){
            LevelOrder(Output);
            std::cout<<std::endl;
        }
         void Delete(){
            PostOrder(Free,root);
            root= 0;
        }
         int Height() const{
             return Height(root);
        }
         int Size(){
            _count= 0;
            PreOrder(Add1,root);
             return _count;
        }
     private:
        BinaryTreeNode<T> *root;
         void PreOrder( void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>* t);
         void InOrder( void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>* t);
         void PostOrder( void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>* t);
         static  void Output(BinaryTreeNode<T>* t){
            std::cout<<t->data<< '   ';
        }
         static  void Free(BinaryTreeNode<T>* t){
            delete t;
        }
         int Height(BinaryTreeNode<T> *t) const;
         static  void Add1(BinaryTreeNode<T>* t){
            _count++;
        }
};
template < class T>
bool BinaryTree<T>::Root(T& x) const
{
     if(root){
        x=root->data;
         return  true;
    }
     else
         return  false;
}
    template < class T>
void BinaryTree<T>::MakeTree( const T& elem,BinaryTree<T>& left,BinaryTree<T>& right)
{
    root= new BinaryTreeNode<T>(elem,left.root,right.root);
    left.root=right.root= 0;
}
    template < class T>
void BinaryTree<T>::BreakTree(T& elem,BinaryTree<T>& left,BinaryTree<T>& right)
{
     if(!root)
         throw  " BadInput ";
    elem=root->data;
    left.root=root->lchild;
    right.root=root->rchild;
    delete root;
    root= 0;
}
    template < class T>
void BinaryTree<T>::PreOrder( void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>* t)
{
     if(t){
        Visit(t);
        PreOrder(Visit,t->lchild);
        PreOrder(Visit,t->rchild);
    }

}
    template < class T>
void BinaryTree<T>::InOrder( void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>* t)
{
     if(t){
        InOrder(Visit,t->lchild);
        Visit(t);
        InOrder(Visit,t->rchild);
    }

}
    template < class T>
void BinaryTree<T>::PostOrder( void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>* t)
{
     if(t){
        PostOrder(Visit,t->lchild);
        PostOrder(Visit,t->rchild);
        Visit(t);
    }

}
template < class T>
void BinaryTree<T>::LevelOrder( void(*Visit)(BinaryTreeNode<T>*u )){
    std::queue<BinaryTreeNode<T>*> qu;
    BinaryTreeNode<T>* t;
    qu.push(root);
     while(!qu.empty()){
        t=qu.front();
         if(t){
            Visit(t);
             if(t->lchild)
                qu.push(t->lchild);
             if(t->rchild)
                qu.push(t->rchild);
        }
        qu.pop();
    }
}
template < class T>
int BinaryTree<T>::Height(BinaryTreeNode<T> *t) const{
     if(!t)
         return  0;
     int hl=Height(t->lchild);
     int hr=Height(t->rchild);
     if(hl>hr)
         return ++hl;
     else
         return ++hr;
}
#endif

二叉树测试代码:

View Code
#include <iostream>
#include  " BinaryTree.h "
using  namespace std;

int count= 0;
BinaryTree< int> a,x,y,z;
template< class T>
void ct(BinaryTreeNode<T> *t){
    count++;
}
void test1(){
    y.MakeTree( 10,a,a);
    z.MakeTree( 20,a,a);
    x.MakeTree( 30,y,z);
    y.MakeTree( 40,x,a);
    y.PreOrder(ct);
    cout<<count<<endl;
    y.PreOutput();
    y.InOutput();
    y.PostOutput();
    y.LevelOutput();
}
void test2(){
    y.MakeTree( 1,a,a);
    z.MakeTree( 2,a,a);
    x.MakeTree( 3,y,z);
    y.MakeTree( 4,x,a);
    cout <<  " Preorder sequence is  ";
    y.PreOutput();
    cout <<  " Inorder sequence is  ";
    y.InOutput();
    cout <<  " Postorder sequence is  ";
    y.PostOutput();
    cout <<  " Level order sequence is  ";
    y.LevelOutput();
    cout <<  " Number of nodes =  ";
    cout << y.Size() << endl;
    cout <<  " Height =  ";
    cout << y.Height() << endl;
    y.PreOrder(ct);
    cout <<  " Count of nodes is  " << count << endl;

}

int main(){
    test2();

}
8. 删除二叉树
要删除一棵二叉树,需要删除其所有节点。可以通过后序遍历在访问一个节点时,把其删除。也就是说先删除左子树,然后右子树,最后删除根。
9. 计算高度
通过进行后序遍历,可以得到二叉树的高度。首先得到左子树的高度 hl,然后得到右子树的高度hr。此时,树的高度为:
max{hl,hr} + 1

10.设置信号放大器

代码如下:

View Code
#include <iostream>
#include  " BinaryTree.h "
using  namespace std;

int tolerance =  3;

class Booster{
    friend  int main();
    friend  void PlaceBoosters(BinaryTreeNode<Booster>*);
     public:
     void Output(ostream&  out) const{
         out<<boost<< '   '<<D<< '   '<<d<< '   ';
    }
     private:
     int D,d;
     bool boost;
};
ostream&  operator<<(ostream&  out, const Booster& x)
{
    x.Output( out);
     return  out;
}
void PlaceBoosters(BinaryTreeNode<Booster>* x){
    BinaryTreeNode<Booster> *y=x->getLChild();
     int degr;
    Booster btr;
    btr.D= 0;
    x->data.D= 0;
     if(y){
        degr=(y->getData()).D+(y->getData()).d;
         if(degr>tolerance){
            y->data.boost= true;
            x->data.D=y->data.d;
        }
         else
            x->data.D=degr;
    }
    y=x->getRChild();
     if(y){
        degr=y->data.D+y->data.d;
         if(degr>tolerance) {
            y->data.boost= true;
            degr=y->data.d;
        }
         if(x->data.D<degr)
            x->data.D=degr;
    }
}
BinaryTree<Booster> T, U, V, W, X, Y;
int main( void)
{
    Booster a, b;
    a.d =  2; a.D = 0; a.boost =  0;
    b.d= 1; b.D= 0; b.boost =  0;
    U.MakeTree(a,X,X);
    V.MakeTree(b,U,X);
    U.MakeTree(a,X,X);
    W.MakeTree(a,U,X);
    b.d= 3;
    U.MakeTree(b,V,W);
    V.MakeTree(a,X,X);
    b.d= 3;
    W.MakeTree(b,X,X);
    Y.MakeTree(a,V,W);
    W.MakeTree(a,X,X);
    T.MakeTree(b,Y,W);
    b.d= 0;
    V.MakeTree(b,T,U);
    V.PostOrder(PlaceBoosters);
    V.PostOutput();
}                                      

 11. 树与二叉树(详细介绍)

 

12. 在线等价类问题 

 (1)利用数组解决

你可能感兴趣的:(数据结构)