• (leetcode)二叉树的前序遍历-c语言实现


    给定一个二叉树,返回它的 前序 遍历。

     示例:

    输入: [1,null,2,3]  
       1
        
         2
        /
       3 
    
    输出: [1,2,3]
    

    进阶: 递归算法很简单,你可以通过迭代算法完成吗?

    前序遍历


    前序遍历首先访问根节点,然后遍历左子树,最后遍历右子树。

    用c语言来实现比较麻烦,现在大概介绍下我的思路,首先题目先要实现一个前序遍历,如果用递归,会比较简单,几行代码就可以实现,但是现在要求使用迭代发来实现。整个遍历过程是,访问根节点,然后遍历其左子树,然后再看左子树是否有其左孩子和右孩子。因为在查看左孩子之后,还要再查看根节点的右孩子,所以每次需要把根节点记录下来,需要存在栈中。所以我们需要实现一个栈,有压栈和出栈操作。另外我们需要一个链表来存放已经访问过的节点,到最后,需要把这些节点统一存储到一个数组中,然后返回。

    下面来看下我码的代码

    /* 链表节点 用于存储输出结果 */
    struct listNode {
        int val;
        struct listNode *next;
    };
    
    struct list {
        int count;
        struct listNode *head;
        struct listNode *tail;
    };
    
    /* 栈节点,用于存储已经遍历过的根节点 */
    struct StackNode
    {
        void *entry;
        struct StackNode *next;
    };
    
    struct stack {
        struct StackNode *top;
    };
    
    void init_stack(struct stack *s)
    {
        s->top = NULL;
    }
    
    void stack_push(struct stack *s, void *np)
    {
        struct StackNode *node = malloc(sizeof(struct StackNode));
        node->entry = np;
        node->next = s->top;
        s->top = node;
    };
    
    void *stack_pop(struct stack *s)
    {
        struct StackNode *np = s->top;
        void *node = np->entry;
        s->top = np->next;
        free(np);
        return node;
    };
    
    bool isEmpty(struct stack *s)
    {
        return (s->top == NULL) ? true : false;
    }
    
    void init_list(struct list *l)
    {
        l->count = 0;
        l->head = NULL;
        l->tail = NULL;
    }
    
    void add_new_node(struct list *l, struct listNode *node)
    {
        if (!l->head)
        {
            l->head = node;
            l->tail = node;
            l->count = 1;
            return;
        }
        
        l->tail->next = node;
        l->tail = node;
        l->count++;
    }

    这些是辅助函数

    int* preorderTraversal(struct TreeNode* root, int* returnSize){
        struct TreeNode *pNode = root;
        struct listNode *newNode = NULL;
        struct list *l = malloc(sizeof(struct list));
        struct stack *s = malloc(sizeof(struct stack));
        int *r = NULL;
        int i = 0;
        struct listNode *head = NULL;
        init_list(l);
        init_stack(s);
        
        while (pNode != NULL || !isEmpty(s))
        {
            if (pNode != NULL)
            {
                newNode = malloc(sizeof(struct listNode));
                newNode->val = pNode->val;
                newNode->next = NULL;
                add_new_node(l, newNode);
                stack_push(s, (void *)pNode);
                pNode = pNode->left;
            }
            else
            {
                pNode = (struct TreeNode *)stack_pop(s);
                pNode = pNode->right;            
            }        
        }
        
        r = malloc(sizeof(int) * l->count);
        head = l->head;
        while(head && i < l->count)
        {
            r[i] = head->val;
            i++;
            head = head->next;
        }
        *returnSize = l->count;
        
        return r;    
    }

    这个是具体的前序遍历函数。

    对应的中序遍历的核心代码如下:

     while (pNode != NULL || !isEmpty(s))
        {
            if (pNode != NULL)
            {
                stack_push(s, (void *)pNode);
                pNode = pNode->left;
            }
            else
            {
                pNode = (struct TreeNode *)stack_pop(s);
                newNode = malloc(sizeof(struct listNode));
                newNode->val = pNode->val;
                newNode->next = NULL;    
                add_new_node(l, newNode);
                pNode = pNode->right;            
            }        
        }

    后序遍历如下:

    while (pNode != NULL || !isEmpty(s))
        {
            if (pNode != NULL)
            {
                stack_push(s, (void *)pNode);
                pNode = pNode->left;
            }
            else
            {
                seek = (struct TreeNode *)stack_seek(s);     
                if (seek->right == NULL || last == seek->right)
                {
                    stack_pop(s);
                    newNode = malloc(sizeof(struct listNode));
                    newNode->val = seek->val;
                    newNode->next = NULL;
                    add_new_node(l, newNode);
                    last = seek;
                }
                else
                {
                    pNode = seek->right;
                }            
            }        
        }
  • 相关阅读:
    vue 环境的搭建及初始化项目
    vue axios 发送post请求,后端接收参数为null
    iOS-WKWebView的使用
    iOS开发GCD(3)-数据安全
    iOS开发-本地存储(偏好设置,Plist,归档)
    ios开发GCD(2)-dispatch_semaphore_t信号量计数器
    ios开发多线程之NSThread
    Runtime消息动态解析与转发流程
    iOS动画-从UIView到Core Animation
    贝塞尔曲线UIBezierPath简单使用
  • 原文地址:https://www.cnblogs.com/xingmuxin/p/11278004.html
Copyright © 2020-2023  润新知