首页 > 其他分享 >数据结构--------二叉树的定义及遍历操作的实现

数据结构--------二叉树的定义及遍历操作的实现

时间:2024-08-03 13:24:34浏览次数:12  
标签:-------- lchild 遍历 queue 二叉树 BTNode rchild NULL root

/*                         二叉树的链式存储以及基本操作                                     */

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

//树的节点
typedef struct BTNode{
    int data;
    struct BTNode *lchild;
    struct BTNode *rchild;
}BTNode,*BTTree;


// 辅助队列节点  
typedef struct LinkNode {  
    BTNode *data;  
    struct LinkNode *next;  
} LinkNode;  

// 辅助队列  
typedef struct LinkQueue {  
    LinkNode *front;  
    LinkNode *rear;  
} LinkQueue;



void visit(BTTree T)
{
    if (T != NULL)
        printf("%d ",T->data);
}


/*                        先序遍历:根左右                                    */
void preOrder(BTTree T)
{
    if (T != NULL)
    {
        visit(T);
        preOrder(T->lchild);
        preOrder(T->rchild);
    }
}

/*                        中序遍历:左根右                                    */
void InOrder(BTTree T)
{
    if (T != NULL)
    {
        InOrder(T->lchild);
        visit(T);
        InOrder(T->rchild);
    }
}


/*                        后序遍历:左右根                                    */
void postOrder(BTTree T)
{
    if (T != NULL)
    {
        postOrder(T->lchild);
        postOrder(T->rchild);
        visit(T);
    }
}


/*                        求树高                                    */
int treeDepth(BTTree T)
{
    if (T == NULL)
        return 0; //空树。树高为0
    else{
        int l = treeDepth(T->lchild);
        int r = treeDepth(T->rchild);
        return l>r ? l+1:r+1; //树的高度等于左右子树高度+1
    }
}

/*                        树的建立                                    */
BTNode* createNode(int data) {  
    BTNode* newNode = (BTNode*)malloc(sizeof(BTNode));  
    newNode->data = data;  
    newNode->lchild = NULL;  
    newNode->rchild = NULL;  
    return newNode;  
} 


/*                        销毁树                                    */
void freeTree(BTTree T) {  
    if (T != NULL) {  
        freeTree(T->lchild);    // 递归释放左子树  
        freeTree(T->rchild);    // 递归释放右子树  
        free(T);                // 释放当前节点  
    }  
}

  

// 初始化队列  
void initQueue(LinkQueue *queue) {  
    queue->front = queue->rear = NULL;  //不带头节点的队列
}  

// 入队  
void enqueue(LinkQueue *queue, BTNode *node) {  
    LinkNode *newNode = (LinkNode *)malloc(sizeof(LinkNode));  
    newNode->data = node;  
    newNode->next = NULL;  
    if (queue->rear == NULL) {  
        queue->front = queue->rear = newNode;  //队列为空,插入第一个新节点后头指针,尾指针都指向第一个节点
    } else {  
        queue->rear->next = newNode;  //队尾入队
        queue->rear = newNode;  //更新队尾指针
    }  
}  

// 出队  
int dequeue(LinkQueue *queue, BTNode **node) {  
    if (queue->front == NULL) {  
        return 0; // 队列为空  
    }  
    LinkNode *temp = queue->front;  
    *node = temp->data;  
    queue->front = queue->front->next;  
    if (queue->front == NULL) {  
        queue->rear = NULL; // 队列变空  
    }  
    free(temp);  
    return 1; // 成功出队  
}  

// 判断队列是否为空  
int isQueueEmpty(LinkQueue *queue) {  
    return queue->front == NULL;  
}  

/* 层序遍历 */  
void levelOrder(BTTree T) {  
    LinkQueue queue;  
    initQueue(&queue);  
    BTNode *p = NULL;  

    if (T != NULL) {  
        enqueue(&queue, T); // 将根节点入队  
        
        while (!isQueueEmpty(&queue)) {  
            dequeue(&queue, &p); // 出队  
            visit(p); // 访问节点  

            // 将左右子节点入队  
            if (p->lchild != NULL) {  
                enqueue(&queue, p->lchild);  
            }  
            if (p->rchild != NULL) {  
                enqueue(&queue, p->rchild);  
            }  
        }  
    }  
}  


int main() {  
    // 创建二叉树  
    BTTree root = createNode(1);  
    root->lchild = createNode(2);  
    root->rchild = createNode(3);  
    root->lchild->lchild = createNode(4);  
    root->lchild->rchild = createNode(5);  
    root->rchild->lchild = createNode(6);  
    root->rchild->rchild = createNode(7);
    root->lchild->lchild->lchild = createNode(8);
    root->rchild->rchild->rchild = createNode(9); 

    // 先序遍历  
    printf("先序遍历: ");  
    preOrder(root);  
    printf("\n");  

    // 中序遍历  
    printf("中序遍历: ");  
    InOrder(root);  
    printf("\n");  

    // 后序遍历  
    printf("后序遍历: ");  
    postOrder(root);  
    printf("\n");  

    //层序遍历
    printf("层序遍历:");
    levelOrder(root);
    printf("\n");

    // 求树高  
    printf("树的高度: %d\n", treeDepth(root)); 
 

    // 释放内存  
    freeTree(root);  

    return 0;  
}  

运行结果如下图

标签:--------,lchild,遍历,queue,二叉树,BTNode,rchild,NULL,root
From: https://blog.csdn.net/bxjsnxidnsnkw/article/details/140889363

相关文章

  • K11505 The Lost cow[USACO-2017-USOpen-B]
    题目描述FarmerJohn最珍贵的奶牛Bessie丢了,他需要把它找回来。幸运的是,农场里只有一条长长的直路,他知道Bessie肯定在这条路上的某个地方。如果我们把这条路看成数轴,假设FarmerJohn所在位置是x,Bessie所在的位置是y(对于John是未知的),如果FarmerJohn知道Bessie的位置,那么他就......
  • 速通c++(周六)
    前言hello大家好,我是文宇。今天是速通c++的最后一天。(周日是愉快的玩耍,学个毛线)今天是一些用循环写的骚操作(娱乐)正文以下是一些在C++中使用循环进行的有趣和骚操作的例子:打印三角形:intn=5;for(inti=0;i<n;i++){for(intj=0;j<=i;j++){cout......
  • coreseek4.1使用sphinx做索引的索引控制shell脚本及逻辑 及 linux安装coreseek4.1的sp
    一、coreseek4.1使用sphinx做索引的索引控制shell脚本及逻辑    sphinx做索引时索引数据来源可以有多种方式,比如数据库mysql,pgsql,mssql,odbc,也可以是python脚本,也可以是xml数据文件,xmlpipe(publish:November1,2017-Wednesday)。    一般来说,如果索引的数据比较简单,......
  • 2024牛客多校6
    第五场太抽象了,失去补题欲望6ACake(A)首先假设字符串已经确定,对Oscar而言,由于一份蛋糕可以为空,在两人都尽可能取最大值的情况下,相当于忽略所有空的部分、只根据字符串的某个前缀\(s'\)划分蛋糕,按照字符串中0占比最大的前缀平均划分一定是最优的。回到游戏第一步,已知Oscar的......
  • 在新页面却加载旧页面的接口
    问题:使用甘特图gantt时,做了一个功能,双击甘特图数据能进行搜索详细情况//3.7双击显示明细gantt.config.details_on_dblclick=true;//监视if(this.eventId){gantt.detachEvent(this.eventId);//先移除之前的事件绑定}thi......
  • 2024年暑假关于线段树和树状数组的小知识点
    1.线段树的树形结构使得存储其的数组应开4N,其中N为元素个数2.多用宏定义使代码更简单3.树状数组求逆序对一般会写成add(a[i],1);quiry(a[i]-1);这会导致当元素值域包含0时传入-1导致死循环,可以在quiry函数判断合法性;一种比较好的写法是干脆add时add(a[i]+1,1),然后直接查......
  • nodejs使用child_process模块启动(exec和spawn)子线程任务,子进程实例的kill()方法无效的
    以下内容在win10环境下的执行分析(这里就不对进程和线程做区分了):child_process.exec和child_process.spawn启动进程的区别。shell<string>Shelltoexecutethecommandwith.SeeShellrequirementsandDefaultWindowsshell.Default:'/bin/sh'onUnix,process.env.C......
  • python 爬虫入门实战——爬取维基百科“百科全书”词条页面内链
    1.简述本次爬取维基百科“百科全书”词条页面内链,仅发送一次请求,获取一个html页面,同时不包含应对反爬虫的知识,仅包含最基础的网页爬取、数据清洗、存储为csv文件。爬取网址url为“https://zh.wikipedia.org/wiki/百科全书”,爬取内容为该页面所有内链及内链标识(下图蓝......
  • 关于:双层for循环
    /*双层for循环*/StringnestedForLoop(intn){StringBuilderres=newStringBuilder();//循环i=1,2,...,n-1,nfor(inti=1;i<=n;i++){//循环j=1,2,...,n-1,nfor(intj=1;j<=n;j++){res......
  • 重庆市软件测试技能大赛——自动化测试(Selenium)篇
    声明如下:个人学习笔记,可以作为复习参考等看一看,在此分享:自动化测试(selenium)篇①点击操作------.click()方法是点击元素的正中心②输入操作------.send_keys()方法使用时先清楚原有内容:.clear()→在进行输入操作③获取元素内信息(属性名,ID内容)操作------.get_attribute()......