zoukankan      html  css  js  c++  java
  • 二叉树的遍历

    二叉树是每个结点最多有两个子树的有序树。通常子树的根被称作“左子树”(left subtree)和“右子树”(right subtree)。

    二叉树常被用作二叉查找树和二叉堆或是二叉排序树。二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。

    二叉树的基本性质:

      (1)二叉树的第i层至多有2的 i-1次方个结点(i>=1);

      (2)深度为k的二叉树至多有2^(k) -1个结点,最少有K个节点;

        最多的原因:2^(1-1)+2^(2-1)+2^(3-1)+....+2^(k-1)=(2^k)-1

        最少的原因:最少一层一个,K层k个节点,不一定全是斜的

      (3)对任何一棵二叉树T,如果其终端结点数(即叶子结点数)为n0,度为2的结点数为n2,则  n0 = n2 + 1。

        原因:若B为总分枝数,n是总节点数

        @1:n=n0+n1+n2

        @2:入枝的数量:B=n-1

        @3:出枝的数量:B=n1+2n2

        得出:n0=n2+1;

      当二叉树是完全二叉树时,可以用顺序存储结构:

      否则的话用顺序结构则会浪费空间,例如当深度是k的右斜树,只有K个节点,需要分配(2^k)-1个存储单元,浪费了(2^k)-1-K个空间

      一般情况下二叉树用二叉链表(binary linked list)存储:

    lchild data rchild

      lchild:左指针域

      data:数据域,存放节点的数据信息

      rchild:右指针域

      二叉树的节点用链式存储结构,其形式定义如下:

      BiNode.h如下:

    template <class T>
    struct BiNode  //结点结构
    {
        T data;
        BiNode<T> *lchild;
        BiNode<T> *rchild;
    };

    //StackElem.h
    template <class T> struct StackElem//非递归后序遍历时,栈元素结构 { BiNode<T> *ptr; int flag; };

    为了避免类的调用者访问BITree类的私有变量root,在勾走函数,析构函数,以及遍历函数中调用了相应的私有函数,

    //BiTree.h
    #include "BiNode.h" #include"StackElem.h" template <class T> class BiTree //二叉树类的定义 { public: BiTree();//二叉链表建立 ~BiTree(); void Prn();//二叉树的输出 void PreOrder();//前序遍历二叉树 void InOrder();//中序遍历二叉树 void PostOrder();//后序遍历二叉树 void LeverOrder();//层序遍历二叉树 private: BiNode<T> *root;//整个二叉树的根 BiNode<T> *creat();//二叉链表的生成 void release(BiNode<T> *bt);//二叉链表的撤销 void PrnIn(BiNode<T>* bt,int depth);//根为bt的二叉树的输出 void PreOrder(BiNode<T>* bt);//前序遍历根为bt的二叉树 void InOrder(BiNode<T>* bt);//中序遍历根为bt的二叉树 void PostOrder(BiNode<T>* bt);//后序遍历根为bt的二叉树 };
    前序遍历的思想:

    中序遍历的思想:

    后序遍历的思想:左孩子标志位是1,右孩子标志位是2


    //BiTree的实现BiTree.cpp:
    #include<iostream>
    #include"BiTree.h"
    using namespace std;
    
    template<class T>
    BiTree<T>::BiTree()
    {
        root=creat();
    }
    
    template<class T>
    BiNode<T> *BiTree<T>::creat()//二叉链表的生成
    {
        BiNode<T> *bt;
        T ch;
        cin>>ch;
        if(ch=='#') bt=NULL;
        else
        {
            bt=new BiNode<T>;
            bt->data=ch;
            bt->lchild=creat();
            bt->rchild=creat();
        }
        return bt;
    }
    
    template <class T>  //析构函数
    BiTree<T>::~BiTree()
    {
        release(root);
    }
    
    template <class T>
    void BiTree<T>::release(BiNode<T> *bt)//二叉链表的撤销
    {
        if(bt!=NULL)
        {
            release(bt->lchild);
            release(bt->rchild);
            delete bt;
        }
        else
            return;
    }
    
    template <class T>
    void BiTree<T>:: Prn()//二叉树的输出
    {
       PrnIn(root,1);
    }
    
    template <class T>
    void BiTree<T>::PrnIn(BiNode<T> *bt,int depth)//根为bt的二叉树的输出
    {
        if(bt!=NULL)
        {
            PrnIn(bt->rchild,depth+1);
            for(int i=0;i<4*(depth-1);i++)
                cout<<" ";
            cout<<"--"<<bt->data<<endl;
            PrnIn(bt->lchild,depth+1);
        }
        else return ;
    }    
    
    //前序遍历算法实现
    template <class T>
    void BiTree<T>::PreOrder()
    {
        PreOrder(root);
    }
    
    //**************前序遍历
    //template <class T>    //前序遍历递归算法
    //void BiTree<T>::PreOrder(BiNode<T> *bt)
    //{
    //    if(bt!=NULL)
    //    {
    //        cout<<bt->data;
    //        PreOrder(bt->lchild);
    //        PreOrder(bt->rchild);
    //    }
    //    else return;
    //}
    
    template <class T>    //前序遍历非递归算法
    void BiTree<T>::PreOrder(BiNode<T> *bt)
    {
        BiNode<T> * s[100]; //
        int top=-1;
        while(top!=-1 || bt!=NULL)
        {
            while(bt!=NULL)
            {
                cout<<bt->data;
                s[++top]=bt;
                bt=bt->lchild;
            }
            if(top!=-1)
            {
                bt=s[top--];
                bt=bt->rchild;
            }
        }
    }
    
    //**************中序遍历
    template <class T>    
    void BiTree<T>::InOrder()
    {
        InOrder(root);
    }
    
    template <class T>    //中序遍历递归算法
    void BiTree<T>::InOrder(BiNode<T>* bt)
    {
        if(bt!=NULL)
        {
            InOrder(bt->lchild);
            cout<<bt->data;
            InOrder(bt->rchild);
        }
        else return ;
    }
    
    
    //template <class T>    //中序遍历非递归算法
    //void BiTree<T>::InOrder(BiNode<T> *bt)
    //{
    //        BiNode<T> *  s[100];//定义一个栈
    //        int top=-1;
    //        while(bt!=NULL||top!=-1)
    //        {
    //            while(bt!=NULL)
    //            {
    //                s[++top]=bt; //根指针Bt入栈
    //                bt=bt->lchild;
    //            }
    //            if(top!=-1) //栈非空
    //            {
    //                bt=s[top--];
    //                cout<<root->data;
    //                bt=bt->rchild;
    //            }
    //        }
    //}
    
    
    //**************后序遍历
    template <class T>
    void BiTree<T>::PostOrder()
    {
      PostOrder(root);
    }
    
    //template <class T>  //后序遍历递归算法
    //void BiTree<T>::PostOrder(BiNode<T>* bt)
    //{
    //    if(bt!=NULL)
    //    {
    //        PostOrder(bt->lchild);
    //        PostOrder(bt->rchild);
    //        cout<<bt->data;
    //    }
    //    else return ;
    //}
    
     //后序遍历非递归算法
    template <class T> 
    void BiTree<T>::PostOrder(BiNode<T> *bt)
    {
        StackElem<T> s[100];
        int top=-1;
        while(bt!=NULL|| top!=-1)//2个条件都不成立才退出循环
        {
            while(bt!=NULL)
            {
                ++top;
                s[top].ptr=bt;//压栈
                s[top].flag=1;//设置标志位
                bt=bt->lchild;////继续访问左子树
            }
            while(top!=-1 && s[top].flag==2) //栈顶标志位是2,弹栈输出
            {
                cout<<s[top--].ptr->data;
            }
            if(top!=-1)//栈顶标志位是1,栈顶标志位设2,bt指向有右孩子
            {
                s[top].flag=2;
                bt=s[top].ptr->rchild;
            }
        }
    }
    
    
    
    
    //以下为层序遍历算法的实现
    template <class T>
    void BiTree<T>::LeverOrder()
    {
        BiNode<T> *bt;
        int front=0;
        int rear=0;
        BiNode<T>* s[20];
        if(root==NULL) return;
        rear=(rear+1)%20;
        s[rear]=root;
        while(front!=rear)
        {
            front=(front+1)%20;
            bt=s[front];
            cout<<bt->data;
            if(bt->lchild!=NULL)
            {
                rear=(rear+1)%20;
                s[rear]=bt->lchild;
            }
            if(bt->rchild!=NULL)
            {
                rear=(rear+1)%20;
                s[rear]=bt->rchild;
            }
        }
    }

    测试Main函数

    #include"BiTree.cpp"
    void main()
    {
        BiTree<char> tree;
        //tree.creat();
        cout<<"二叉树的输出:"<<endl;
        tree.Prn();
        cout<<endl;
        
        cout<<"前序遍历输出:"<<endl;
        tree.PreOrder();
        cout<<endl;
    
        cout<<"中序遍历输出:"<<endl;
        tree.InOrder();
        cout<<endl;
    
        cout<<"后序遍历输出:"<<endl;
        tree.PostOrder();
        cout<<endl;
    
        cout<<"层序遍历输出:"<<endl;
        tree.LeverOrder();
        cout<<endl;
    }


  • 相关阅读:
    BF算法和KMP算法
    Python课程笔记 (五)
    0268. Missing Number (E)
    0009. Palindrome Number (E)
    0008. String to Integer (atoi) (M)
    0213. House Robber II (M)
    0198. House Robber (E)
    0187. Repeated DNA Sequences (M)
    0007. Reverse Integer (E)
    0006. ZigZag Conversion (M)
  • 原文地址:https://www.cnblogs.com/DonAndy/p/6028077.html
Copyright © 2011-2022 走看看