题目一:不分行从上到下打印二叉树。从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。二叉树节点定义如下:
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};
思路:相当于二叉树的层次遍历,我们可以通过队列辅助打印:每次打印一个节点的时候,如果该节点有子节点,则把该节点的子节点放入队列的尾部。接下来到队列的头部取出最早进入队列的节点,重复前面的操作,直至队列中所有的节点都被打印出来。
*以下代码未经验证
#define QUEUE_SIZE 1024
typedef struct queue {
int head;
int tail;
BinaryTreeNode *data[QUEUE_SIZE]; // 暂不考虑溢出情况
}my_queue;
void queue_push(my_queue *queue, BinaryTreeNode * val) {
queue->data[queue->tail] = val;
queue->tail++;
}
BinaryTreeNode * queue_pop(my_queue *queue) {
BinaryTreeNode * val = queue->data[queue->head];
queue->head++;
return val;
}
int queue_size(my_queue *queue) {
return queue->tail - queue->head;
}
my_queue *tree_help_queue;
void PrintFromTopToBottom(BinaryTreeNode *pTreeRoot) {
if (NULL == pTreeRoot) {
return;
}
queue_push(tree_help_queue, pTreeRoot); // 根入队列
while (0 != queue_size(tree_help_queue)) {
BinaryTreeNode *tmp = queue_pop(tree_help_queue);
printf(" %d ", tmp->m_nValue);
if (pTreeRoot->m_pLeft != NULL) { // 如果该节点有子节点,则把该节点的子节点放入队列的尾部
queue_push(tree_help_queue, pTreeRoot->m_pLeft);
}
if (pTreeRoot->m_pRight != NULL) { // 如果该节点有子节点,则把该节点的子节点放入队列的尾部
queue_push(tree_help_queue, pTreeRoot->m_pRight);
}
}
}
题目二:分行从上到下打印二叉树。从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印,每一层打印到一行。
思路:为了把二叉树的每一行单独打印到一行中,我们需要两个变量,一个变量表示在当前层中还没有打印的节点数;另一个变量表示下一层节点数。
void PrintFromTopToBottomLINE(BinaryTreeNode *pTreeRoot) {
if (NULL == pTreeRoot) {
return;
}
queue_push(tree_help_queue, pTreeRoot); // 根入队列
int nextlevelnum = 0;
int nowlevelneedp = 1;
while (0 != queue_size(tree_help_queue)) {
if (pTreeRoot->m_pLeft != NULL) { // 如果该节点有子节点,则把该节点的子节点放入队列的尾部
queue_push(tree_help_queue, pTreeRoot->m_pLeft);
nextlevelnum++;
}
if (pTreeRoot->m_pRight != NULL) { // 如果该节点有子节点,则把该节点的子节点放入队列的尾部
queue_push(tree_help_queue, pTreeRoot->m_pRight);
nextlevelnum++;
}
BinaryTreeNode *tmp = queue_pop(tree_help_queue);
printf(" %d ", tmp->m_nValue);
nowlevelneedp--;
if (0 == nowlevelneedp) {
printf("\n");
nowlevelneedp = nextlevelnum;
nextlevelnum = 0;
}
}
}
题目三:之字形打印二叉树。请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二行按照从右到左的顺序打印,其他行以此类推。
思路:之字形顺序打印二叉树需要两个栈,在打印某一层的时候,将下一层的节点保存到栈中。如果当前打印的是奇数层,则先保存左子叶节点;如果当前打印的层数是偶数层,则先保存右子叶节点再保存左子叶节点到第二个栈中。为什么需要两个栈,因为一个栈要打印,一个栈保存下一层子叶节点。
#define STACK_SIZE 1024
typedef struct stack {
int base;
int top;
BinaryTreeNode *data[STACK_SIZE]; // 暂不考虑溢出情况
}my_stack;
BinaryTreeNode *stack_top(my_stack *stack) {
BinaryTreeNode *val = stack->data[stack->top];
return val;
}
void stack_push(my_stack *stack, BinaryTreeNode *pTreeRoot) {
stack->data[stack->top] = pTreeRoot;
stack->top++;
}
BinaryTreeNode *stack_pop(my_stack *stack) {
stack->top--;
BinaryTreeNode *val = stack->data[stack->top];
return val;
}
int stack_size(my_stack *stack) {
int size = stack->top - stack->base;
return size;
}
my_stack *tree_help_stack[2]; // need init
void zhiPrintFromTopToBottom(BinaryTreeNode *pTreeRoot) {
if (NULL == pTreeRoot) {
return;
}
int current = 0;
int next = 1;
stack_push(tree_help_stack[current], pTreeRoot); // 根入栈0
while (0 != stack_size(tree_help_stack[current]) || 0 != stack_size(tree_help_stack[next])) {
BinaryTreeNode *tmp = stack_pop(tree_help_stack[current]);
printf(" %d ", tmp->m_nValue);
if (0 == current) {
if (pTreeRoot->m_pLeft != NULL) { // 如果该节点有子节点,该层为从右向左打印,栈先放左子节点
stack_push(tree_help_stack[next], pTreeRoot->m_pLeft);
}
if (pTreeRoot->m_pRight != NULL) {
stack_push(tree_help_stack[next], pTreeRoot->m_pLeft);
}
}
else {
if (pTreeRoot->m_pRight != NULL) { // 如果该节点有子节点,该层为从左向右打印,栈先放右子节点
stack_push(tree_help_stack[next], pTreeRoot->m_pLeft);
}
if (pTreeRoot->m_pLeft != NULL) {
stack_push(tree_help_stack[next], pTreeRoot->m_pLeft);
}
}
// 交换两个栈
if (0 == stack_size(tree_help_stack[current])) {
printf("\n");
current = 1 - current;
next = 1 - next;
}
}
}