返回二叉树的前序遍历(非递归实现)

 

题目描述:

分析:本题目需要借助于栈实现(栈用数组实现,其中元素类型是二叉树结点的指针,即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;
}

 

 

 

 

 
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值