• 4.1 二叉树的基本操作


    #include <iostream>
    #include <string.h>
    #include <stack>
    #include <queue>
    
    using namespace std;
    
    typedef struct node{
        char data;
        struct node *lchild;
        struct node *rchild;
    }Node;
    
    void CreateTree(Node * &T){
        char ch;
        cin>>ch;
    
        if(ch=='#') T=NULL;
        else{
            T=new Node;
            T->data=ch;
            CreateTree (T->lchild);
            CreateTree (T->rchild);
        }
    }
    
    // 递归先序
    void PreOrderR(Node *T){
        if(T) {
            cout<<T->data<<" ";
            PreOrderR(T->lchild);
            PreOrderR(T->rchild);
        }
    }
    
    // 递归中序
    void InOrderR(Node *T){
        if(T){
           InOrderR(T->lchild);
           cout<<T->data<<" ";
           InOrderR(T->rchild);
        }
    }
    
    // 递归后序
    void PostOrderR(Node *T){
        if(T){
            PostOrderR(T->lchild);
            PostOrderR(T->rchild);
            cout<<T->data<<" ";
        }
    }
    
    // 循环先序
    void PreOrderL(Node *T){
    
        stack <Node *> S;
    
        Node *p=T;
    
        while(p || !S.empty()){
    
            while(p){        
                cout<<p->data<<" ";
    
                S.push(p);
    
                p=p->lchild;
    
            }               
            if(!S.empty()){ 
                p=S.top();
    
                S.pop();
    
                p=p->rchild;
    
            }
    
        }
    
    }
    
    // 循环中序
    void InOrderL(Node *T){
        stack <Node *> S;
        Node *p=T;
        while(p || !S.empty()){
            if(p){
                S.push(p);
                p=p->lchild;
            }
            else{
                p=S.top();
                cout<<p->data<<" ";
                S.pop();
                
                p=p->rchild;
            }
        }
    
    }
    // 循环后续
    void PostOrderL(Node *T){
        stack <Node *> S;          // 栈里面存放树的结点指针即可,而非整个结点数据
        Node *p=T,*r=NULL;
        while(p || !S.empty()){
            if(p){
                S.push(p); 
                p=p->lchild;
            }
            else{
                p=S.top();
                if(p->rchild && p->rchild!=r){
                    p=p->rchild;
                    S.push(p);
                    p=p->lchild;
                }
                else{
                    S.pop();
                    cout<<p->data<<" ";
                    r=p;
                    p=NULL;
                }
            }
        }    
    }
    
    // 层序遍历
    void LevelOrder(Node *T){
        queue <Node *> Q;
        Node *p;
        Q.push(T);                     // 根结点入队
        while(!Q.empty()){
            p=Q.front();
            Q.pop();
            cout<<p->data<<" ";
            
            if(p->lchild) Q.push(p->lchild);
            if(p->rchild) Q.push(p->rchild);
        }
    }
    
    // 递归求二叉树高度
    int DepthR(Node *T){
        int ldepth,rdepth;
        if(!T) return 0;              // 空树,高度为0。也就是初值
        ldepth=DepthR(T->lchild);
        rdepth=DepthR(T->rchild);
        return ldepth>rdepth ? ldepth+1:rdepth+1;
    }
    
    // 循环求二叉树高度
    int DepthL(Node *T){
        if(!T) return 0;
        int front=-1,rear=-1, last=0,level=0;
        queue <Node *> Q;
        Q.push(T); rear++;
        Node *p;
        while(front<rear){
            p=Q.front(); front++; Q.pop();
            if(p->lchild){
                Q.push(p->lchild);rear++;
            }
            if(p->rchild){
                Q.push(p->rchild);rear++;
            }
            if(front==rear){         // 主体类似层序遍历,前后不同
                level++;
                last=rear; 
            }
        }
        return level;
    }
    
    // 删除结点
    void Del(Node * &T){
        if(T){
            Del(T->lchild);
            Del(T->rchild);
            free(T);
            T=NULL;
        }
    }
    
    // 删除以X为根的子树
    void DelX(Node *T,char X){
        queue <Node *> Q;
        Node *p;
        if(T){
            if(T->data==X) {Del(T);return;}
            Q.push(T);
            while(!Q.empty()){          // 把X的左右子树先删除,区分左右
                p=Q.front(); Q.pop();
                if(p->lchild){
                    if(p->lchild->data==X) Del(p->lchild);
                    else Q.push(p->lchild);
                }
                if(p->rchild){
                    if(p->rchild->data==X) Del(p->rchild);
                    else Q.push(p->rchild);
                }
            }
        }
    }
    
    // 获得父节点
    Node * GetParent(Node *T,char X){
        if(T){
            if(T->lchild)               // 只有child存在的情况下,才能访问其数据域,否则出错
                if(T->lchild->data==X) return T;
            if( T->rchild)
                if(T->rchild->data==X) return T;
            GetParent(T->lchild,X);
            GetParent(T->rchild,X);
        }
    }
    
    int main(){
        Node *T;
        cout<<"先序建立二叉树,如 ABDG##H###CE#I##F## :"<<endl;
        CreateTree(T);
        cout<<"递归先序: ";      PreOrderR(T);       cout<<endl;
        cout<<"循环先序: ";      PreOrderL(T);       cout<<endl;
    
        cout<<"递归中序: ";      InOrderR(T);        cout<<endl;
        cout<<"循环中序: ";      InOrderL(T);        cout<<endl;
    
        cout<<"递归后序: ";      PostOrderR(T);      cout<<endl;
        cout<<"循环后序: ";      PostOrderL(T);      cout<<endl;
    
        cout<<"层序遍历: ";      LevelOrder(T);      cout<<endl;
        
        cout<<"DepthR:"<<DepthR(T)<<endl<<"DepthL:"<<DepthR(T)<<endl;
       
        Node *p=GetParent(T,'E');
        cout<<"E的父节点:"<<p->data<<endl;
        
        DelX(T,'C');
        cout<<"层序遍历: ";      LevelOrder(T);      cout<<endl;
        
        return 0;
    }
    
    #if 0
                  A
                 / 
                /   
               /     
              B       C
             /       /
            /       /  
           D     #  E    F
          /       /    /
         G   H    #  I  #  #
        /   /      /
       #  # #  #    #  #
      
        ABDG##H###CE#I##F##
    
    #endif
  • 相关阅读:
    jmeter之ServerAgent监控资源
    jmeter之线程组循环次数
    mysql增删查改、存储过程
    [剑指Offer] 37.数字在排序数组中出现的次数
    [剑指Offer] 36.两个链表的第一个公共结点
    [剑指Offer] 35.数组中的逆序对
    [剑指Offer] 34.第一个只出现一次的数
    [剑指Offer] 33.丑数
    [OS] 进程相关知识点
    [C/C++] C/C++中数字与字符串之间的转换
  • 原文地址:https://www.cnblogs.com/Alexagender/p/10806324.html
Copyright © 2020-2023  润新知