(leetcode)二叉樹的層次遍歷-c語言實現


這段代碼,在后面跑測試用例時,出現了stack-overflow,但是原因還不清楚。

問題如下:

 二叉樹的層次遍歷
 

給定一個二叉樹,返回其按層次遍歷的節點值。 (即逐層地,從左到右訪問所有節點)。

例如:
給定二叉樹: [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回其層次遍歷結果:

[
  [3],
  [9,20],
  [15,7]
]

因為要輸出一個二維數組,那么我需要定義一個兩重鏈表,具體定義如下:
/* 鏈表節點 用於存儲輸出結果 */
struct listNode {
    int val;
    struct listNode *next;
};

struct list {
    int count;
    struct listNode *head;
    struct listNode *tail;
    struct list *next;
};

struct list_list
{
    int count;
    struct list *head;
    struct list *tail;
};

鏈表的一些操作如下:

void init_list(struct list *l)
{
    l->count = 0;
    l->head = NULL;
    l->tail = NULL;
    l->next = NULL;
}

void init_list_list(struct list_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++;
}

void add_new_list(struct list_list *ll, struct list *l)
{
    if (ll->head == NULL)
    {
        ll->head = l;
        ll->tail = l;
        ll->count = 1;
        return;
    }
    
    ll->tail->next = l;
    ll->tail = l;
    ll->count++;
}

鏈表創建如下:

struct list_list * create_list_list()
{
    struct list_list *ll = malloc(sizeof(struct list_list));
    if (ll)
    {
        init_list_list(ll);
    }
    return ll;
}
struct list * create_list()
{
    struct list *l = malloc(sizeof(struct list));
    if (l)
    {
        init_list(l);
    }
    
    return l;
}

另外需要定義一個隊列,用於存放每個樹節點

/* 隊列節點,用於存儲已經遍歷過的根節點 */
struct queue_node
{
    void *entry;
    struct queue_node *next;
};

struct queue {
    struct queue_node *front;
    struct queue_node *rear;
};

隊列的一些簡單操作實現如下:

/* 隊列節點,用於存儲已經遍歷過的根節點 */
struct queue_node
{
    void *entry;
    struct queue_node *next;
};

struct queue {
    struct queue_node *front;
    struct queue_node *rear;
};

void init_queue(struct queue *q)
{
    q->front = NULL;
    q->rear = NULL;
}

void queue_push(struct queue *q, void *np)
{
    struct queue_node *node = malloc(sizeof(struct queue_node));
    node->entry = np;
    node->next = NULL;
    
    if (q->rear == NULL)
    {
        q->rear = node;
        q->front = node;
    }
    else
    {
        q->rear->next = node;
        q->rear = node;
    }  
}

void *queue_pop(struct queue *q)
{
    struct queue_node *np = q->front;
    void *entry = NULL;
    if (np)
    {
        entry = np->entry;
        if (np->next == NULL)
            q->rear = NULL;
        q->front = np->next;
        free(np);        
    }
    
    return entry;
}
struct queue * create_queue()
{
    struct queue *q = malloc(sizeof(struct queue));
    if (q)
    {
        init_queue(q);
    }
    return q;
}

主函數的具體實現思想為,遍歷根節點,將其存入隊列中,然后在隊列中插入一個flag標記,之后進入一個while循環,循環中,每次從隊列中取出一個成員,將該成員存入到用於輸出的二層鏈表中,然后判斷其左右孩子是否為空,不為空,則其左右孩子入隊列。然后再循環,當從隊列中取出的是flag標志后,並且隊列中還沒空,那么就在這個隊列中再插入一個flag標志,表示這一層的遍歷結束,可以輸出這一層的鏈表。如此循環,直到所有節點都入隊列,讀到最后一個flag標記,並且隊列為空,那么整個遍歷流程結束。后面就是把二層鏈表輸出成一個二維數組。

代碼如下:

int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes){
    struct list_list *ll;
    struct list *subList;
    struct listNode *head;    
    struct queue *q;
    struct TreeNode *pNode = NULL;
    struct listNode *newnode = NULL;
    int **r;
    int *subr;
    struct list *l;
    int i,j;
    int *size;
    int *resize;
    
    if (!root || !returnSize || !returnColumnSizes)
        return;
    
    q = create_queue();
    ll = create_list_list();
    l = create_list();
    add_new_list(ll, l);
    queue_push(q, (void*)root);
    queue_push(q, FINISH_FALG);

    while (q->front != NULL)
    {
        pNode = (struct TreeNode *)queue_pop(q);
        if (pNode == FINISH_FALG)
        {
            if (q->front == NULL)
                break;
            /* 創建新的鏈表,在總鏈表中插入新的鏈表 */
            l = create_list();
            add_new_list(ll, l);
            
            /* 在當前隊列中再插入一個終結標志 */
            queue_push(q, FINISH_FALG);
            continue;
        }
        
        /* 該節點插入到當前鏈表中 */
        newnode = create_node(pNode->val);
        add_new_node(l, newnode);
        
        /* 將當前節點的左右孩子加入隊列中 */
        if (pNode->left != NULL)
        {
            queue_push(q, (void*)pNode->left);
        }
        if (pNode->right != NULL)
        {
            queue_push(q, (void*)pNode->right);
        }        
    }
    
    r = (int **)malloc(sizeof(int *) * ll->count);
    resize = (int *)malloc(sizeof(int *) * ll->count);
    subList = ll->head;
    while(subList && i < ll->count)
    {
        subr = (int *)malloc(sizeof(int) * subList->count);
        head = subList->head;
        j = 0;
        while(head && j < subList->count)
        {
            subr[j] = head->val;
            j++;
            head = head->next;
        }

        resize[i] = subList->count;
        
        r[i] = subr;
        i++;
        subList = subList->next;
    }
    *returnSize = ll->count;
    *returnColumnSizes = resize;
    return r;
}

 

 

 


免責聲明!

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



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