(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; } } }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM