二叉树层次遍历括号表示法C语言,(leetcode)二叉树的层次遍历-c语言实现

给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。

例如:

给定二叉树: [3,9,20,null,null,15,7],

3

/ \

9 20

/ \

15 7

返回其层次遍历结果:

[

[3],

[9,20],

[15,7]

]

因为要输出一个二维数组,那么我需要定义一个两重链表,具体定义如下:

/*链表节点 用于存储输出结果*/

structlistNode {intval;struct listNode *next;

};structlist {intcount;struct listNode *head;struct listNode *tail;struct list *next;

};structlist_list

{intcount;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(structlist_list));if(ll)

{

init_list_list(ll);

}returnll;

}struct list *create_list()

{struct list *l = malloc(sizeof(structlist));if(l)

{

init_list(l);

}returnl;

}

另外需要定义一个队列,用于存放每个树节点

/*队列节点,用于存储已经遍历过的根节点*/

structqueue_node

{void *entry;struct queue_node *next;

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

};

队列的一些简单操作实现如下:

/*队列节点,用于存储已经遍历过的根节点*/

structqueue_node

{void *entry;struct queue_node *next;

};structqueue {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(structqueue_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);

}returnentry;

}

struct queue *create_queue()

{struct queue *q = malloc(sizeof(structqueue));if(q)

{

init_queue(q);

}returnq;

}

主函数的具体实现思想为,遍历根节点,将其存入队列中,然后在队列中插入一个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;inti,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;returnr;

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值