题目描述:
分析:本题目和上一题“返回二叉树的前序遍历”类似。也是通过栈实现,但是与前序的区别是:前序遍历将将左路结点入栈的同时依次访问结点,而中序遍历将只是左路结点依次压入栈,但是此时并不访问(由于中序遍历是左-根-右),而是出栈的时候访问栈顶元素,再访问栈顶元素的右子树(子问题)。
在C语言中,我们先得利用单链表实现栈以及部分接口。(由于要访问栈顶元素的右子树,因此栈元素类型是TreeNode*,即二叉树结点的指针)。
栈的简单实现以及部分接口:
typedef struct TreeNode* STDataType;
typedef struct Stack
{
STDataType* _a;
int _top;
int _capacity;
}Stack;
void StackInit(Stack* ps,int n);//初始化,容量为n
void StackDestory(Stack* ps);
void StackPush(Stack* ps, STDataType x);//入栈
void StackPop(Stack* ps);//出栈
STDataType StackTop(Stack* ps);//取栈顶元素
int StackSize(Stack* ps);//取栈中元素个数
int StackEmpty(Stack* ps);//判断栈是否为空
void StackInit(Stack* ps, int n)
{
assert(ps);
ps->_a = (STDataType*)malloc(sizeof(STDataType)*n);
ps->_top = 0;
ps->_capacity = n;
}
void StackDestory(Stack* ps)
{
assert(ps);
free(ps->_a);
ps->_a = NULL;
ps->_top = 0;
ps->_capacity = 0;
}
void StackPush(Stack* ps, STDataType x)//入栈
{
assert(ps);
if (ps->_capacity == ps->_top)//栈满了,增容
{
STDataType* tmp = (STDataType*)realloc(ps->_a, ps->_capacity*2*sizeof(STDataType));
if (tmp != NULL)
{
ps->_a = tmp;
}
ps->_capacity *= 2;
}
ps->_a[ps->_top] = x;
ps->_top++;
}
void StackPop(Stack* ps)//出栈
{
assert(ps);
if (ps->_top > 0)
{
ps->_top--;
}
}
STDataType StackTop(Stack* ps)//取栈顶元素
{
assert(ps);
return ps->_a[ps->_top - 1];
}
int StackSize(Stack* ps)//取栈中元素个数
{
assert(ps);
return ps->_top;
}
int StackEmpty(Stack* ps)//判断栈是否为空
{
assert(ps);
return ps->_top == 0 ? 0 : 1;//空返回0
}
二叉树的中序遍历(非递归实现):
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Return an array of size *returnSize.
* Note: The returned array must be malloced, assume caller calls free().
*/
int* inorderTraversal(struct TreeNode* root, int* returnSize) {
//第一次循环计算结点个数,为下面的开空间做准备
Stack st;
StackInit(&st,20);
struct TreeNode* cur=root;
while(cur!=NULL || StackEmpty(&st)!=0)
{
while(cur!=NULL)//将左路结点依次入栈
{
StackPush(&st, cur);
(*returnSize)++;
cur=cur->left;
}
struct TreeNode* top=StackTop(&st);
StackPop(&st);
cur=top->right;//访问左路结点的右子树(子问题)
}
//第二次循环存访问顺序
int* array=(int*)malloc((*returnSize)*sizeof(int));
int i=0;
cur=root;
while(cur!=NULL || StackEmpty(&st)!=0)
{
while(cur!=NULL)//将左路结点依次入栈
{
StackPush(&st, cur);
cur=cur->left;
}
struct TreeNode* top=StackTop(&st);
array[i++]=top->val;//取到栈顶元素才访问该结点
StackPop(&st);
cur=top->right;//访问左路结点的右子树(子问题)
}
return array;
}