• 手写栈(递归转化为非递归)


    递归的本质是通过栈来保存状态,然后再次调用自己进入新的状态,然后函数返回的时候回到上次保存的状态。

    如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归的。当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归。尾递归函数的特点是在回归过程中不用做任何操作,就是没有回溯过程,所以我们可以直接将尾递归写成循环

    更一般的递归,想要转化为非递归,就需要模拟栈(手写栈)的行为。

    遍历的递归和非递归实现:

    #include<cstdio>
    #include<stack>
    using namespace std;
    struct node{
        int id;
        node *l=NULL,*r=NULL;
    }a[100];
    void PreOrderTraverse(node i){//递归先序遍历 
        printf("%d ",i.id);//输出根 
        if(i.l)PreOrderTraverse(*i.l);//遍历左子树 
        if(i.r)PreOrderTraverse(*i.r);//遍历右子树 
    }
    void InOrderTraverse(node i){//递归中序遍历 
        if(i.l)InOrderTraverse(*i.l);//遍历左子树 
        printf("%d ",i.id);//输出根 
        if(i.r)InOrderTraverse(*i.r);//遍历右子树 
    }
    void PostOrderTraverse(node i){//递归后序遍历 
        if(i.l)PostOrderTraverse(*i.l);//遍历左子树 
        if(i.r)PostOrderTraverse(*i.r);//遍历右子树 
        printf("%d ",i.id);//输出根 
    }
    void PreOrderTraverse(node* i){//非递归先序遍历 
        stack<node>s;
        node x;
        while(i||!s.empty()){
            while(i){
                s.push(*i);
                printf("%d ",i->id);//输出根 
                i=i->l;//遍历左子树 
            }
            x=s.top();s.pop();
            i=x.r;//遍历右子树
            
        }
    }
    void InOrderTraverse(node* i){//非递归中序遍历 
        stack<node>s;
        node x;
        while(i||!s.empty()){
            while(i){
                s.push(*i);
                i=i->l;//遍历左子树 
            }
            x=s.top();s.pop();
            printf("%d ",x.id);//输出根 
            i=x.r;//遍历右子树
            
        }
    }
    void PostOrderTraverse(node* i){//非递归后序遍历 
        stack<pair<node,bool> >s;
        pair<node,bool> x;
        while(i||!s.empty()){
            while(i){
                s.push(make_pair(*i,0));
                i=i->l;//遍历左子树 
            }
            x=s.top();s.pop();
            if(x.second)printf("%d ",x.first.id);//如果右子树遍历过则输出根
            else s.push(make_pair(x.first,1)),i=x.first.r;//如果右子树没遍历则遍历右子树
            
        }
    }
    int main(){
        for(int i=1;i<99;i++){
            a[i].id=i;
            if(i%2)a[i>>1].r=&a[i];
            else a[i>>1].l=&a[i];
        }
        InOrderTraverse(a[1]);printf("
    ");
        InOrderTraverse(&a[1]);printf("
    ");
        PreOrderTraverse(a[1]);printf("
    ");
        PreOrderTraverse(&a[1]);printf("
    ");
        PostOrderTraverse(a[1]);printf("
    ");
        PostOrderTraverse(&a[1]);printf("
    ");
        return 0;
    }
  • 相关阅读:
    排列 POJ
    [kuangbin带你飞]专题二十一 概率&期望 部分题解
    队列最大值&滑动窗口最大值【剑指offer】
    Python实现可视化界面多线程豆瓣电影信息爬虫,并绘制统计图分析结果
    剑指offer【复杂链表的复制】
    树上博弈——从根节点先后走向叶子节点输赢【递归水题】
    给一个长度为n的字符串,找出长度为m的最小字典子序列【单调栈】
    Hrbust 1814 小乐乐的化妆品【01背包】
    Hrbust 1541集合划分 & Hrbust 2002幂集【dp】
    Hrbust 1333 GG的关心【01背包】
  • 原文地址:https://www.cnblogs.com/bennettz/p/6726005.html
Copyright © 2020-2023  润新知