Leetcode题库 598.N叉树的前序遍历(递归&迭代 C实现)

一、递归法

1、解析/思路

children为Node指针数组
ret数组记录每个节点的val值
pos记录ret数组下一个待填入val值的下标
Recur函数功能:将root节点的val传入ret,并遍历其children

流程:
判断当前节点是否为空
为空 return
非空 记录当前节点val值 并且for循环遍历children

2、代码

void Recur(struct Node* root,int* ret,int* pos){
    if(root==NULL) return;
    ret[(*pos)++]=root->val;
    for(int i=0;i<root->numChildren;i++){
        Recur(root->children[i],ret,pos);
    }
}

int* preorder(struct Node* root, int* returnSize) {
    int * ret = (int *)malloc(sizeof(int) * 10000);
    int pos=0;
    Recur(root,ret,&pos);
    *returnSize=pos;
    return ret;
}

二、迭代法

1、解析/思路

Node栈:压入子节点尚未遍历完成的父节点
P_S_Top:栈顶下标
Flag栈:压入父节点即将遍历的下一个子节点下标
P_F_Top:栈顶下标
p指向当前节点
flag为当前p节点的即将遍历的子节点的下标
ret记录遍历的val值

流程:
判断root节点是否为空
为空 return
非空 p指向root节点 并记录val值
迭代开始
判断当前节点p即将遍历子节点下标flag是否小于其子节点个数
小于则说明当前节点p还有子节点未遍历
则将P_S_Top加1,当前节点p压入Node栈中
P_F_Top加1,flag+1压入Flag栈中(flag+1代表p下一遍历子节点)
p指向p[flag]
flag置为0(0当前p下一遍历子节点下标)
大于等于说明当前节点p无子节点
判断Node栈是否还有当前p节点的父节点(也就是Node栈是否为空)
非空则说明存在父节点
则将当前节点p指向Node栈顶,P_S_Top减1
flag=Flag栈顶元素,P_F_Top减1(Flag栈顶元素表示Node栈顶节点下一遍历子节点)
为空则说明当前节点p无父节点
无父无子表示遍历完成

补充:
1、最后的p节点一定指向root
2、只要理解了flag与p的关系,思路一目了然

2、代码

int* preorder(struct Node* root, int* returnSize) {
    //Node栈
    struct Node *P_Stack[10000];
    int P_S_Top=-1;

    //Flag栈
    int P_Flag[10000];
    int P_F_Top=-1;

    //初始化
    struct Node* p=root;
    int flag=0;    
    int *ret=(int*)malloc(sizeof(int)*10000);
    *returnSize=0;
    if(root==NULL){
        return ret;
    }
    p=root;
    ret[(*returnSize)++]=p->val;
    //迭代开始
    while(1){
        if(flag<p->numChildren){//还有未遍历的子节点,当前节点压栈,p指向子节点
            P_Stack[++P_S_Top]=p;
            P_Flag[++P_F_Top]=flag+1;
            p=p->children[flag];
            flag=0;
            ret[(*returnSize)++]=p->val;
        }
        else{//没有待遍历的子节点,准备弹栈
            if(P_S_Top!=-1){//栈不为空,p指向栈顶,并且弹栈
                p=P_Stack[P_S_Top--];
                flag=P_Flag[P_F_Top--];
            }
            else{//栈为空,程序结束
                break;
            }
        }

    }
    return ret;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值