题目描述:
分析:本题目需要借助于栈实现(栈用数组实现,其中元素类型是二叉树结点的指针,即TreeNode*,因为我们从栈顶取出元素时,要找到其右子树)。从根结点开始,访问左路节点,并依次将访问过的结点入栈,直到左路结点访问完。然后依次访问栈顶元素的右子树(模拟子问题)。
在C语言中,自己得先实现栈,以及栈的部分接口。另外由于我们事先不知道二叉树有多少个结点,因此还得先遍历一遍求出结点个数,再根据这个个数动态申请空间大小。
栈的简单实现:
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* preorderTraversal(struct TreeNode* root, int* returnSize) {
//先遍历一遍,求出节点个数
Stack st;
StackInit(&st, 20);
struct TreeNode* cur=root;
while(cur!=NULL || StackEmpty(&st)!=0)
{
while(cur!=NULL)//访问左路结点并入栈
{
(*returnSize)++;
StackPush(&st, cur);
cur=cur->left;
}
//来到这说明,当前左路结点已都入栈,准备访问栈顶元素的右子树
struct TreeNode* top=StackTop(&st);
StackPop(&st);
cur=top->right;//访问栈顶元素的右子树(子问题)
}
//再遍历一遍,存遍历数据
int* array=(int*)malloc(sizeof(int)*(*returnSize));
int i=0;
cur=root;
while(cur!=NULL || StackEmpty(&st)!=0)
{
while(cur!=NULL)//访问左路结点并入栈
{
array[i++]=cur->val;
StackPush(&st, cur);
cur=cur->left;
}
//来到这说明,当前左路结点已都入栈,准备访问栈顶元素的右子树
struct TreeNode* top=StackTop(&st);
StackPop(&st);
cur=top->right;//访问栈顶元素的右子树(子问题)
}
return array;
}