- 前序遍历:首先访问根节点,然后遍历左子树,最后遍历右子树(根->左->右)
前序遍历的递归算法
思路:
- 访问根节点
- 遍历左子树
- 遍历右子树
代码如下:
//二叉树的前序遍历(递归)
void BinaryTreePrevOrder(BTNode* root){
if (root){
putchar(root->data);
BinaryTreePrevOrder(root->lChild);
BinaryTreePrevOrder(root->rChild);
}
}
前序遍历的非递归算法
思路:
借助栈来实现
- 传入二叉树根节点
- 打印当前节点(如果该节点有右孩子就将右孩子入栈)
- 如果该节点有左孩子则访问,如果没有,就访问栈顶(返回步骤2,直至栈空)
图解非递归:
代码如下:
//二叉树的前序遍历(递归)
void BinaryTreePrevOrderNonR(BTNode* root)
{
Stack st;
BTNode * cur = root; //从根开始
StackInit(&st, 100);
//不能用栈是否为空进行判断(根节点的左边全部遍历结束,访问根节点的右孩子时,此时栈为空)
while (cur)
{
putchar(cur->data); //访问当前节点
if (cur->rChild) //如果有右孩子,右孩子入栈
{
StackPush(&st, cur->rChild);
}
if (cur->lChild) //如果有左孩子,访问左孩子
{
cur = cur->lChild;
}
else //没有左孩子就取栈顶
{
cur = StackTop(&st); //取到空时,遍历结束,循环跳出
StackPop(&st);
}
}
StackDestory(&st);
}
栈函数实现如下:
typedef char BTDataType;
// 二叉链的结构体
typedef struct BinaryTreeNode {
BTDataType data; // 当前节点值域
struct BinTreeNode* lChild; // 指向当前节点左孩子
struct BinTreeNode* rChild;// 指向当前节点右孩子
}BTNode;
typedef BTNode* StDataType;
// 栈的结构体
typedef struct Stack {
StDataType* array; // 指向动态开辟的数组
size_t size; // 有效数据个数
size_t capicity; // 容量空间的大小
}Stack;
void StackInit(Stack* psl, size_t capicity)
{
assert(psl);
psl->capicity = capicity;
psl->array = (StDataType *)malloc(capicity * sizeof(StDataType));
assert(psl->array);
psl->size = 0;
}
void StackDestory(Stack* psl)
{
assert(psl);
if (psl->array)
{
free(psl->array);
psl->array = NULL;
psl->size = 0;
psl->capicity = 0;
}
}
void CheckCapacity(Stack* psl)
{
assert(psl);
if (psl->size == psl->capicity)
{
psl->capicity *= 2;
psl->array = (StDataType *)realloc(psl->array, psl->capicity * sizeof(StDataType));
}
}
void StackPush(Stack* psl, StDataType x)
{
assert(psl);
CheckCapacity(psl);
psl->array[psl->size] = x;
psl->size++;
}
void StackPop(Stack* psl)
{
assert(psl || psl->size);
psl->size--;
}
StDataType StackTop(Stack* psl)
{
if (StackIsEmpty(psl))
{
return (StDataType)0;
}
return psl->array[psl->size - 1];
}
int StackIsEmpty(Stack* psl)
{
return psl->size == 0;
}