二叉树——链式存储

本文详细介绍了二叉树的结构定义,包括节点定义及生成新节点的函数。接着,通过先序、中序、后序遍历展示了二叉树的三种主要遍历方法,并给出了对应的遍历结果。此外,还提供了计算二叉树高度的递归算法,层次遍历的实现以及查找和修改节点值的方法。最后,讨论了如何销毁二叉树以及提供了测试代码以验证所有功能。
摘要由CSDN通过智能技术生成

一、二叉树结构定义

节点定义:

typedef char ElemType;
typedef struct tagBitNode
{
    char data;
    struct tagBitNode *left;
    struct tagBitNode *right;
} BitNode;

二、构建二叉树

手动构建一个如图所示的二叉树。
在这里插入图片描述
新节点生成函数:

// 生成新节点
BitNode *newBitNode(ElemType data)
{
    BitNode *root = (BitNode *)malloc(sizeof(BitNode));
    if(!root)
    {
        return NULL;//failed
    }
    root->data = data;
    root->left = NULL;
    root->right = NULL;
    return root;

}//end of function newBitNode

三、深度遍历

3.1 先序遍历

二叉树先序遍历的过程:
(1)访问根节点
(2)先序遍历左子树
(3)先序遍历右子树
递归算法:

//基于先序遍历的递归算法: 根左右
void preOrderTraverse(BitNode *root)
{
    if(root)
    {
        printf("%c ", root->data);
        preOrderTraverse(root->left);
        preOrderTraverse(root->right);
    }
}// end of function preOrderTraverse

先序遍历结果:

A B D G C E F

3.2 中序遍历

中序遍历的过程:
(1)中序遍历左子树
(2)访问根节点
(3)中序遍历右子树
递归算法:

// 中序遍历: 左根右
void inOrderTraverse(BitNode *root)
{
    if(root)
    {
        inOrderTraverse(root->left);
        printf("%c ", root->data);
        inOrderTraverse(root->right);
    }
}// end of function inOrderTraverse

中序遍历结果:

D G B A E C F

3.3 后序遍历

后序遍历的过程;
(1)后序遍历左子树
(2)后序遍历右子树
(3)访问根节点
递归算法:

// 后序遍历: 左右根
void postOrderTraverse(BitNode *root)
{
    if(root)
    {
        postOrderTraverse(root->left);
        postOrderTraverse(root->right);
        printf("%c ", root->data);
    }
}//end of function postOrderTraverse

后序遍历结果:

G D B E F C A

四、计算二叉树的高度

递归算法:

// 计算二叉树高,基于后序遍历
int bitTreeDepth(BitNode *root)
{
    if(!root) return 0;//基线条件,空树高度为0
    int leftDepth = bitTreeDepth(root->left);
    int rightDepth = bitTreeDepth(root->right);
    return leftDepth > rightDepth ? ++leftDepth : ++rightDepth;
}

计算结果:

Depth: 4

五、层次遍历

层次遍历需要借助队列来实现。
(1)树非空,则根节点入队
(2)访问队首节点,然后将其出队。若有左孩子,将其左孩子入队;若有右孩子,将其右孩子入队
(3)重复(2)过程至队列空。

(偷个懒,直接使用C++的STL库中queue)

// 层序遍历,借助队列来实现
void levelOrderTraverse(BitNode *root)
{
    if(!root) return;   //空树,则结束

    std::queue<BitNode*> q;
    q.push(root);

    while(!q.empty())
    {
        BitNode *temp = q.front();
        printf("%c ", temp->data);
        q.pop();

        if(temp->left) q.push(temp->left);
        if(temp->right) q.push(temp->right);
    }
}

层序遍历结果:

A B C D E F G

六、查找和修改节点的值

基于先序遍历整棵树,将符合查询条件的节点都进行修改。使用时需确保待修改的值存在。如果查找的值不存在,无任何返回值。

// 将指定值修改为给定值,前提是指定值必须存在且唯一
// 基于先序遍历
void change(BitNode *root, ElemType data, ElemType newData)
{
    if(root)
    {
        if(root->data == data)
        {
            root->data = newData;
        }
        change(root->left, data, newData);
        change(root->right, data, newData);
    }
}

七、销毁二叉树

只能用后序遍历的顺序销毁二叉树。

// 销毁二叉树,必须用后序方式
// 先释放孩子节点,再释放根节点
void destroyBitTree(BitNode *root)
{
    if(root)
    {
        destroyBitTree(root->left);
        destroyBitTree(root->right);
        free(root);
    }
}//end of function destroyBitTree

八、测试代码

void test()
{

    BitNode *root = newBitNode('A');
    BitNode *nodeB = newBitNode('B');
    BitNode *nodeC = newBitNode('C');
    BitNode *nodeD = newBitNode('D');
    BitNode *nodeE = newBitNode('E');
    BitNode *nodeF = newBitNode('F');
    BitNode *nodeG = newBitNode('G');

    root->left = nodeB;
    root->right = nodeC;

    nodeB->left = nodeD;
    nodeD->right = nodeG;

    nodeC->left = nodeE;
    nodeC->right = nodeF;

    preOrderTraverse(root);
    printf("\n");

    inOrderTraverse(root);
    printf("\n");

    postOrderTraverse(root);
    printf("\n");

    printf("Depth: %d", bitTreeDepth(root));
    printf("\n");

    levelOrderTraverse(root);
    printf("\n");

    destroyBitTree(root);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值