二叉树的遍历

二叉树的遍历

本文中会用到栈和队列两种数据结构,先放在这里

/**
*
* 以二叉树节点为元素的循环队列,用于实现二叉树的层序遍历
* 
*/
struct TQueue {
	int front;
	int rear;
	BNode** elem;
};

//初始话一个队列
void InitTQueue(TQueue& queue);
//入队
int EnTQueue(TQueue& queue, BNode* x);
//出队
BNode* DeTQueue(TQueue& queue);
//队列是否为空
int isQueueEmpty(TQueue& queue);
//队列是否满了
int isQueueFull(TQueue& queue);
/**
*
* 以二叉树节点为元素的栈,用于实现二叉树的中序非递归遍历
* 
*/
struct TStack {
	BNode** elem;
	int top;
};
//创建栈
TStack creakAStack();
//栈是否为空
int isStackEmpty(TStack stack);
//站是否满
int isStackFull(TStack stack);
//入栈
int Push(TStack& stack, BNode* element);
//出栈
BNode* Pop(TStack& stack);
/**
* 二叉树节点结构体的定义和二叉树相关函数的声明
*/

struct BNode
{
	BNode* left;
	BNode* right;
	int val;
};
//按照中序序列生成二叉树
//如:ABD#G###CE##FH###
BNode* CreateTree();
//中序
void InOrder(BNode* root);
//先序
void PreOrder(BNode* root);
//后序
void PostOrder(BNode* root);
//中序非递归
void IterInorder(BNode* root);
//层序遍历
void LevelOrder(BNode* root);
//求叶节点
int Leaf(BNode* root);
//度为1
int NodesOne(BNode* root);
//度为2
int NodesTwo(BNode* root);
//节点数
int Nodes(BNode* root);
//树的高度
int Height(BNode* root);
//表达式求值
//例如:+1##/*6##3##2##
int Eval(BNode* root);

二叉树是一种递归定义,每一个非空节点都可以有0到2个节点,不断向下递归下去。因此在处理上面二叉树的常见问题时,递归非常常见

创建一个二叉树

//ABD#G###CE##FH###
BNode* CreateTree()
{
    BNode* bt;
    char ch;
    scanf("%c", &ch);
    if (ch == '#')bt = nullptr;
    else {
        MALLOC(bt, sizeof(BNode), BNode*);
        bt->val = ch;
        bt->left = CreateTree();
        bt->right = CreateTree();
    }
    return bt;
}

这个函数中,视#为空,使用中序序列初始话一颗二叉树

二叉树的中序,先序、后续遍历

void InOrder(BNode* root)
{
    if (root != nullptr) {
        InOrder(root->left);
        printf("%c", root->val);
        InOrder(root->right);
    }
}

void PreOrder(BNode* root)
{
    if (root != nullptr) {
        printf("%c", root->val);
        InOrder(root->left);
        InOrder(root->right);
    }
}

void PostOrder(BNode* root)
{
    if (root != nullptr) {
        InOrder(root->left);
        InOrder(root->right);
        printf("%c", root->val);
    }
}

中序非递归遍历

void IterInorder(BNode* root)
{
    BNode* temp;
    temp = root;
    TStack stack = creakAStack();
    while (temp!= nullptr) {
        while (temp!=nullptr) {
            Push(stack, temp);
            temp = temp->left;
        }
        if (!isStackEmpty(stack)) {
            temp = Pop(stack);
            printf("%c", temp->val);
        }
        temp = temp->right;
    }
}

中序非递归遍历用到了栈,思路和中序递归差不多,只不过用栈来保存之前经过的节点。

从根节点不断向左走,直到为空,将节点都压入栈中。

之后不断将节点从栈中弹出,将这个节点访问之后,在转向他的右节点。

层序遍历

void LevelOrder(BNode* root)
{
    TQueue queue;
    InitTQueue(queue);
    BNode* temp=nullptr;
    EnTQueue(queue, root);
    while (!isQueueEmpty(queue)) {
        temp = DeTQueue(queue);
        printf("%c", temp->val);
        if (temp->left != nullptr) {
            EnTQueue(queue, temp->left);
        }
        if (temp->right != nullptr) {
            EnTQueue(queue, temp->right);
        }
    }
}

层序遍历就是将二叉树一层一层遍历掉。如何实现呢。这里用到了队列:

先将根节点入队,然后开始循环,根节点出队,如果左节点不为空,左节点入队,右节点不为空,右节点入队。再次让一个节点出队,再做如此处理,直到最后一层。

posted @ 2021-11-27 19:13  博客是个啥?  阅读(49)  评论(0编辑  收藏  举报