数据结构与算法学习笔记九-二叉树的链式存储表示法和实现(C语言)

目录

前言

1.二叉树的链式存储

2.二叉链表的表示和实现

1.定义

2.创建

4.中序遍历二叉树

5.后序遍历二叉树

6.后序遍历二叉树

7.完整代码


前言

    这篇博客主要介绍二叉树的链式存储结构。

1.二叉树的链式存储

       上篇文章中介绍了二叉树的顺序存储结构,在最坏的情况下,比如二叉树仅有左子树或者右子树的时候,我们仍然需要为不存在的节点分配大量的存储空间,这无疑会造成存储空间的浪费。考虑到二叉树的三要素:数据域、右子树指针、左子树指针,我们可以考虑使用链式存储来表示二叉树。

        当我们使用数据域、左右子树指针表示二叉树的结构时,得到的二叉树链表成为二叉链表。我们还可以再二叉链表的基础上增加一个父结点的数据域,这样得到的二叉树链表称为三叉链表。

        二叉链表和三叉链表的存储结构如下图所示:

                        图1.二叉链表和三叉链表的表示                

2.二叉链表的表示和实现

1.定义

typedef char TelemType;
typedef int Status;
typedef struct BiTNode{TelemType data;//数据域struct BiTNode * lchild,*rchild;//左右孩子指针
}BiTNode,*BiTree;

2.创建

// 创建二叉树
Status createBiTree(BiTree *tree) {TelemType data;scanf("%c", &data); // 读取节点数据if (data == '#') {*tree = NULL; // 空节点} else {*tree = (BiTNode *)malloc(sizeof(BiTNode));if (!*tree) {exit(EXIT_FAILURE); // 内存分配失败return 0;}(*tree)->data = data; // 存储节点数据createBiTree(&((*tree)->lchild)); // 递归创建左子树createBiTree(&((*tree)->rchild)); // 递归创建右子树}return 1; // 创建成功
}

3.先序遍历二叉树

// 先序遍历二叉树
Status preOrderTraverse(BiTree tree) {if (tree == NULL) {return 1; // 空树,遍历结束}// 访问根节点printf("%c ", tree->data);// 递归遍历左子树preOrderTraverse(tree->lchild);// 递归遍历右子树preOrderTraverse(tree->rchild);return 1; // 遍历成功
}

4.中序遍历二叉树

// 中序遍历二叉树
Status inOrderTraverse(BiTree tree) {if (tree == NULL) {return 1; // 空树,遍历结束}// 递归遍历左子树inOrderTraverse(tree->lchild);// 访问根节点printf("%c ", tree->data);// 递归遍历右子树inOrderTraverse(tree->rchild);return 1; // 遍历成功
}

5.后序遍历二叉树

// 后序遍历二叉树
Status postOrderTraverse(BiTree tree) {if (tree == NULL) {return 1; // 空树,遍历结束}// 递归遍历左子树postOrderTraverse(tree->lchild);// 递归遍历右子树postOrderTraverse(tree->rchild);// 访问根节点printf("%c ", tree->data);return 1; // 遍历成功
}

6.后序遍历二叉树

// 后序遍历二叉树
Status postOrderTraverse(BiTree tree) {if (tree == NULL) {return 1; // 空树,遍历结束}// 递归遍历左子树postOrderTraverse(tree->lchild);// 递归遍历右子树postOrderTraverse(tree->rchild);// 访问根节点printf("%c ", tree->data);return 1; // 遍历成功
}

7.完整代码

#include <stdio.h>
#include <stdlib.h>typedef char TelemType;
typedef int Status;
typedef struct BiTNode{TelemType data;//数据域struct BiTNode * lchild,*rchild;//左右孩子指针
}BiTNode,*BiTree;// 创建二叉树
Status createBiTree(BiTree *tree) {TelemType data;scanf("%c", &data); // 读取节点数据if (data == '#') {*tree = NULL; // 空节点} else {*tree = (BiTNode *)malloc(sizeof(BiTNode));if (!*tree) {exit(EXIT_FAILURE); // 内存分配失败return 0;}(*tree)->data = data; // 存储节点数据createBiTree(&((*tree)->lchild)); // 递归创建左子树createBiTree(&((*tree)->rchild)); // 递归创建右子树}return 1; // 创建成功
}// 先序遍历二叉树
Status preOrderTraverse(BiTree tree) {if (tree == NULL) {return 1; // 空树,遍历结束}// 访问根节点printf("%c ", tree->data);// 递归遍历左子树preOrderTraverse(tree->lchild);// 递归遍历右子树preOrderTraverse(tree->rchild);return 1; // 遍历成功
}// 中序遍历二叉树
Status inOrderTraverse(BiTree tree) {if (tree == NULL) {return 1; // 空树,遍历结束}// 递归遍历左子树inOrderTraverse(tree->lchild);// 访问根节点printf("%c ", tree->data);// 递归遍历右子树inOrderTraverse(tree->rchild);return 1; // 遍历成功
}// 后序遍历二叉树
Status postOrderTraverse(BiTree tree) {if (tree == NULL) {return 1; // 空树,遍历结束}// 递归遍历左子树postOrderTraverse(tree->lchild);// 递归遍历右子树postOrderTraverse(tree->rchild);// 访问根节点printf("%c ", tree->data);return 1; // 遍历成功
}int main(int argc, const char *argv[]) {BiTree tree;printf("请输入二叉树的前序序列(使用'#'表示空节点):\n");createBiTree(&tree);printf("二叉树创建成功!\n");printf("先序遍历二叉树..\n");preOrderTraverse(tree);printf("\n中序遍历二叉树...\n");inOrderTraverse(tree);printf("\n后序遍历二叉树...\n");postOrderTraverse(tree);printf("\n");return 0;
}

        例如我们要生成如下图所示的二叉树。控制台输入ABD##E##CF##G##

图1.测试二叉树

        控制台打印结果如下:

        OK,打印结果正确。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/9632.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【核武器】2024 年美国核武器-20240507

2024年5月7日,《原子科学家公报》发布了最新版的2024美国核武器手册 Hans M. Kristensen, Matt Korda, Eliana Johns, and Mackenzie Knight, United States nuclear weapons, 2024, Bulletin of the Atomic Scientists, 80:3, 182-208, DOI: https://doi.org/10.1080/00963…

Pandas数据取值与选择

文章目录 第1关&#xff1a;Series数据选择第2关&#xff1a;DataFrame数据选择方法 第1关&#xff1a;Series数据选择 编程要求 本关的编程任务是补全右侧上部代码编辑区内的相应代码&#xff0c;要求实现如下功能&#xff1a; 添加一行数据&#xff0c;时间戳2019-01-29值为…

【问题分析】锁屏界面调起google语音助手后壁纸不可见【Android 14】

1 问题描述 为系统和锁屏分别设置两张不同的壁纸&#xff0c;然后在锁屏界面长按Power调起google语音助手后&#xff0c;有时候会出现壁纸不可见的情况&#xff0c;如以下截图所示&#xff1a; 有的时候又是正常的&#xff0c;但显示的也是系统壁纸&#xff0c;并非是锁屏壁纸…

Android system property运作流程源码分析

一.序 前文分析了build.prop这个系统属性文件的生成&#xff0c;每个属性都有一个名称和值&#xff0c;他们都是字符串格式。属性被大量使用在Android系统中&#xff0c;用来记录系统设置或进程之间的信息交换。属性是在整个系统中全局可见的。每个进程可以get/set属性&#x…

傻傻分不清楚:JDK/JRE/JVM的区别和联系

在Java开发的世界里&#xff0c;JDK、JRE和JVM是三个经常听到的术语。 对于初学者来说&#xff0c;它们的概念和区别可能会让人感到困惑。 这篇文章详细解释下三个组件的含义、它们之间的区别和联系。 一&#xff0c;JDK&#xff1a;Java Development Kit JDK是Java开发工具…

MOS管栅极驱动自举电路设计

自举式驱动电路工作原理 自举式电路在高电压栅极驱动电路中是很有用的,其工作原理如下: 当 VS 降低到 IC 电源电压 VDD以下(至少要比VDD低一个二极管压降) 或下拉至地时 (低端开关导通,高端开关关断),电源 VDD 通过自举电阻RBOOT,和自举二极管DBOOT,对自举电容CBOOT…

一套pacs医学影像存档与通讯系统源码 PACS系统的起源、趋势、工作流程

PACS系统的起源 医学影像信息系统最初是从处理放射科的数字图像发展起来的。医学影像信息系统的前身是医学影像存档与通信系统&#xff08;PACS&#xff0c;Picture Archiving & Communication System&#xff09;&#xff0c;最先推动PACS发展的动力来自于传统的相机厂家…

【已解决】QT C++中QLineEdit不可粘贴输入

本博文源于生产实际&#xff0c;主要解决LineEdit不可粘贴输入的情况。下面将进行具体分析 问题来源 输入框只能一个个输入&#xff0c;不可复制粘贴。 分析 给QLineEdit装一个监听事件&#xff0c;监听它的事件即可。 问题解决步骤 问题一共分为三步&#xff1a; 书写监…

C++反汇编——多态,面试题01

文章目录 1.C的三大特性1.1封装1.2继承1.3多态1.3.1 虚函数1.3.2 多态代码反汇编分析。反汇编分析1——基类指针指向子类对象&#xff0c;构造过程。反汇编分析2——基类指针指向子类对象&#xff0c;调用虚函数getPrice()过程。反汇编分析3——基类对象&#xff0c;调用虚函数…

electron-vite工具打包后通过内置配置文件动态修改接口地址实现方法

系列文章目录 electronvitevue3 快速入门教程 文章目录 系列文章目录前言一、实现过程二、代码演示1.resources/env.json2.App.vue3.main/index.js4.request.js5.安装后修改 前言 使用electron-vite 工具开发项目打包完后每次要改接口地址都要重新打包&#xff0c;对于多环境…

思维导图如何用AI生成?借助这几款工具

思维导图如何用AI生成&#xff1f;在数字化时代&#xff0c;思维导图作为一种高效的信息组织与展示工具&#xff0c;被广泛应用于学习、工作和项目管理中。随着人工智能技术的飞速发展&#xff0c;AI生成思维导图已成为现实&#xff0c;极大地提升了创建思维导图的效率和创意。…

翻译《The Old New Thing》 - Restating the obvious about the WM_COMMAND message

Restating the obvious about the WM_COMMAND message - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20060302-10/?p32093 Raymond Chen 2006年03月02日 关于 WM_COMMAND 消息的显而易见的知识点补充 简要 本文详细解释了 WM_COMMAND 消息…

Django 静态文件管理与部署指南

title: Django 静态文件管理与部署指南 date: 2024/5/10 17:38:36 updated: 2024/5/10 17:38:36 categories: 后端开发 tags: WebOptCDN加速DjangoCompressWebpackStaticDeployCICD-ToolsSecStatic 第一章&#xff1a;介绍 Django 静态文件的概念和重要性 在 Web 开发中&a…

Linux diff命令(比较两个文件或目录的内容差异)

文章目录 Linux diff 命令详解教程基本用法比较文件输出解释 递归比较&#xff08;-r&#xff09;示例代码 控制输出格式统一格式&#xff08;-u&#xff09;上下文格式&#xff08;-c&#xff09; 高级选项忽略所有空白差异&#xff08;-w&#xff09;仅报告文件是否不同 Linu…

纯 CSS 实现标签自动显示超出数量

现代 CSS 强大的令人难以置信。 这次我们来用 CSS 实现这样一个功能&#xff1a;有多个宽度不同的标签水平排列&#xff0c;当外层宽度不足时&#xff0c;会提示超出的数量&#xff0c;演示效果如下 如果让我用 JavaScript来实现估计都有点折腾&#xff0c;毕竟宽度都是动态的…

有什么方便实用的黏土特效教程?6个软件教你快速进行特效制作

有什么方便实用的黏土特效教程&#xff1f;6个软件教你快速进行特效制作 作为时尚小达人&#xff0c;你自己是否想要制作出属于自己的黏土特效照片呢&#xff1f;比如下面几种。 看到这些黏土特效软件有没有心动&#xff0c;下面我也为大家详细的介绍一下可以制作出对应特效的…

Java 集合-List

集合主要分为两组(单列集合, 双列集合) Connection 接口有两个重要的子接口LIst 和 Set, 它们的实现子类都是单列集合, Map 接口的实现子类是双列集合, 存放的是 K-V Connection 接口 Collection 接口和常用方法 下面以 ArrayList 演示一下 add: 添加单个元素remove: 删除指…

Socket学习记录

本次学习Socket的编程开发&#xff0c;该技术在一些通讯软件&#xff0c;比如说微信&#xff0c;QQ等有广泛应用。 网络结构 这些都是计算机网络中的内容&#xff0c;我们在这里简单回顾一下&#xff1a; UDP(User Datagram Protocol):用户数据报协议;TCP(Transmission Contr…

这是一关于DSC相关的文档

这是一关于DSC相关的文档 上面这幅图清晰的展示了somewhat flat的像素图示

机器学习算法应用——关联规则分析(4-4)

关联规则分析&#xff08;4-4&#xff09; 关联规则分析&#xff08;Association Rule Mining&#xff09;是一种基于频繁项集的分析方法&#xff0c;它以最常出现在一起的元素之间的关系作为分析对象&#xff0c;主要用于发掘大数据中隐藏的关联规则&#xff0c;是数据挖掘技术…