二叉树操作思想总结

  1. 定义节点结构体

定义节点结构体,结构体中包含着两个整型变量和两个指针变量,其中指针变量的数据类型与节点结构体数据类型是同一个数据类型

第一个整型变量是数据域,记录数据

第二个整型变量是节点的编号

第一个指针变量指向左子树

第二个指针变量指向右子树

  1. 完全二叉树的创建(编号与节点个数)

此函数是一个回调函数,会一直调用自己,直到判断出既没有左子树又没有右子树

定义一个节点指针变量,用malloc在堆区开辟空间,需要进行数据类型转换

给指针变量里用来保存节点编号的整型变量赋上参数值(一般创建的第一个点是根节点,给节点编号为1)

判断当前节点是否有左子树

如果有左子树,创建的节点的左子树调用函数本身(完全二叉树的创建,算是回调函数)

如果没有左子树,则将左子树初始化指向空

判断当前节点是否有右子树

如果有右子树,创建的节点的右子树调用函数本身(完全二叉树的创建,算是回调函数)

如果没有右子树,则将右子树初始化指向空

最后返回根节点的地址

  1. 先序遍历

此函数是一个回调函数,会一直调用自己,直到判断出既没有左子树又没有右子树

首先判断根节点是否指向空

如果指向空,则啥都不干,结束函数

如果根节点没指向空,则打印自身的编号

继续判断是否存在左子树

如果存在,调用本函数(判断节点是否指向空,不指向空打印编号,指向空结束)

再继续判断是否存在右子树

如果存在,调用本函数(判断节点是否指向空,不指向空打印编号,指向空结束)

  1. 中序遍历

此函数是一个回调函数,会一直调用自己,直到判断出既没有左子树又没有右子树

首先判断根节点是否指向空

如果指向空,则啥都不干,结束函数

继续判断是否存在左子树

如果存在,调用本函数(判断节点是否指向空,不指向空打印编号,指向空结束)

如果根节点没指向空,则打印自身的编号

再继续判断是否存在右子树

如果存在,调用本函数(判断节点是否指向空,不指向空打印编号,指向空结束)

  1. 后序遍历

此函数是一个回调函数,会一直调用自己,直到判断出既没有左子树又没有右子树

首先判断根节点是否指向空

如果指向空,则啥都不干,结束函数

继续判断是否存在左子树

如果存在,调用本函数(判断节点是否指向空,不指向空打印编号,指向空结束)

再继续判断是否存在右子树

如果存在,调用本函数(判断节点是否指向空,不指向空打印编号,指向空结束)

如果根节点没指向空,则打印自身的编号

  1. 注意事项

先序遍历、中序遍历、后序遍历的区别是在于本身节点打印顺序先后的区别

  1. 源码

为对照方便,贴上源码

bitree.h

#ifndef _BITREE_H_
#define _BITREE_H_

#include <stdio.h>
#include <stdlib.h>

//定义数据类型
typedef int Datatype;
//定义结点结构体
typedef struct node{
    Datatype data;  //数据
    int code; //编号
    struct node *pLchild;
    struct node *pRchild;
}bitree;

//完全二叉树的创建
//i:根节点的编号,一般为1,n:结点个数
bitree *BitreeCreateTotal(int i, int n);
//先序遍历
void BitreeOrderFront(bitree *root);
//中序遍历
void BitreeOrderMiddle(bitree *root);
//后序遍历
void BitreeOrderBack(bitree *root);

#endif

bitree.c

#include "bitree.h"

//完全二叉树的创建
//i:根节点的编号,一般为1,n:结点个数
bitree *BitreeCreateTotal(int i, int n)  
{
    //先创建根节点并设置编号
    bitree *root = (bitree *)malloc(sizeof(bitree));
    root->code = i;

    //判断当前结点是否有左子树
    if(2 * i <= n)
    {
        root->pLchild = BitreeCreateTotal(2*i, n);
    }
    else
    {
        root->pLchild = NULL;
    }

    //判断是否存在右子树
    if(2 * i + 1 <= n)
    {
        root->pRchild = BitreeCreateTotal(2 * i + 1, n);
    }
    else
    {
        root->pRchild = NULL;
    }
    
    return root;
}

//先序遍历
void BitreeOrderFront(bitree *root)
{
    if(root == NULL)
    {
        return ;
    }

    //遍历根节点
    printf("%d ", root->code);

    //判断是否存在左子树
    if(root->pLchild != NULL)
    {
        BitreeOrderFront(root->pLchild);
    }

    //判断是否存在右子树
    if(root->pRchild != NULL)
    {
        BitreeOrderFront(root->pRchild);
    }
}

//中序遍历
void BitreeOrderMiddle(bitree *root)
{
    if(root == NULL)
    {
        return ;
    }

    //判断是否存在左子树
    if(root->pLchild != NULL)
    {
        BitreeOrderMiddle(root->pLchild);
    }

    //遍历根节点
    printf("%d ", root->code);

    //判断是否存在右子树
    if(root->pRchild != NULL)
    {
        BitreeOrderMiddle(root->pRchild);
    }
}

//后序遍历
void BitreeOrderBack(bitree *root)
{
    if(root == NULL)
    {
        return ;
    }

    //判断是否存在左子树
    if(root->pLchild != NULL)
    {
        BitreeOrderBack(root->pLchild);
    }

    //判断是否存在右子树
    if(root->pRchild != NULL)
    {
        BitreeOrderBack(root->pRchild);
    }

    //遍历根节点
    printf("%d ", root->code);
}

main.c

#include "bitree.h"

int main(int argc, char const *argv[])
{
    bitree *b = BitreeCreateTotal(1, 10);
    
    BitreeOrderFront(b);
    putchar(10);
    BitreeOrderMiddle(b);
    putchar(10);
    BitreeOrderBack(b);
    putchar(10);
    
    return 0;
}

8.作业:

扑克牌游戏:执行一个动作,将第一张牌放在牌尾,然后再取出一张牌,接着在将下一张牌放在牌尾,然后再取出一张,以此类推,要求取出牌的顺序是1-13,求初始时扑克牌的顺序

提示:结合队列实现,可以使用反推的思想

void Poker(int *mysort)
{
    //创建一个队列
    linkqueue *lq = LinkqueueCreate();

    //将扑克牌的位置入队
    //假设已经将牌的顺序排列好了,所以没一张牌的位置是确定的
    int i;
    for(i = 1; i <= 13; i++)
    {
        LinkqueueInput(lq, i);
    }

    //循环的执行出队,再入队,然后再出队一张,以此类推
    int num;
    int n = 1;
    while(!LinkqueueIsEmpty(lq))
    {
        //出队一个数据
        num = LinkqueueOutput(lq);
        //将其入队
        LinkqueueInput(lq, num);

        //再出队一张牌
        num = LinkqueueOutput(lq);

        mysort[num-1] = n;
        n++;
    }

    return ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小徐的记事本

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值