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

目录

前言

1.数组和结构体相关的一些知识

1.数组

2.结构体数组

3.递归遍历数组

2.二叉树的顺序存储表示法和实现

1.定义

2.初始化

3.先序遍历二叉树

4.中序遍历二叉树

5.后序遍历二叉树

6.完整代码


前言

        二叉树的非递归的表示和实现。

1.数组和结构体相关的一些知识

1.数组

        在C语言中,可以将数组作为参数传递给函数。当数组作为参数传递时,实际上传递给函数的是数组的地址,而不是数组的副本。这意味着,在函数内部对数组进行的修改会影响到原始数组。

        例如在下面的代码中,我们把数组名作为参数传递给modifyArray函数,在函数中修改数组的值,main函数打印原来的数组,会发现原来的数组也被修改。

#include <stdio.h>
#include <stdlib.h>void modifyArray(int *s,int size){for (int i = 0; i < size; i++) {s[i] = s[i] * 10;}printf("\n");
}int main(int argc, const char *argv[]) {int arr[5] = {1,2,3,4,5};int length = sizeof(arr) / sizeof(arr[0]);printf("修改之前的数组:\n");for (int i =  0; i < length;i++) {printf("%d\t",arr[i]);}modifyArray(arr,length);printf("\n修改之前的数组:\n");for (int i =  0; i < length;i++) {printf("%d\t",arr[i]);}printf("\n");return 0;
}

        当然上述的函数我们还可以写成数组的形式。

void modifyArray(int s[],int size){for (int i = 0; i < size; i++) {s[i] = s[i] * 10;}printf("\n");
}

2.结构体数组

        在上述的代码中,我们使用数组操作基本数据类型非常的方便。当时当我们需要自定义数据类型的时候,上述的代码就不满足我们的需求了。例如我们需要表示学生数组的时候,因为每个学生都有自己的属性,姓名,年龄等等,这个时候我们就需要使用结构体数组。

        在数据结构中,我们有时候需要使用数组表示一些数据类型,因此有时候我们需要把数组声明为全局函数。代码实例如下:

#include <stdio.h>
#include <stdlib.h>// 学生结构体
typedef struct {char name[50]; // 姓名int age;       // 年龄
} Student;int main() {// 创建一个包含3个学生对象的数组并初始化Student students[3] = {{"张三", 20},{"李四", 21},{"王五", 22}};// 输出学生信息printf("学生信息如下:\n");for (int i = 0; i < 3; i++) {printf("学生姓名:%s\n", students[i].name);printf("学生年龄:%d\n", students[i].age);}return 0;
}

3.递归遍历数组

        在我们使用数组表示二叉树的时候,需要递归遍历数组,这里需要您了解数组递归的写法。

        在这个示例中以下面的代码为例,,recursivePrint 函数用于递归地遍历数组并打印数组中的元素。它接受三个参数:arr 表示数组,size 表示数组的大小,index表示当前遍历的索引位置。函数首先检查索引是否超出数组范围,如果是,则递归终止。否则,它打印当前索引处的数组元素,然后递归调用自身,传入下一个索引位置。在 main函数中,我们创建一个数组并调recursivePrint 函数来遍历打印数组元素。

#include <stdio.h>// 递归遍历数组并打印数组中的元素
void recursivePrint(int arr[], int size, int index) {// 递归终止条件:当索引超出数组范围时,结束递归if (index >= size) {return;}// 打印当前索引处的数组元素printf("%d ", arr[index]);// 递归调用,遍历下一个元素recursivePrint(arr, size, index + 1);
}int main() {int arr[] = {1, 2, 3, 4, 5};int size = sizeof(arr) / sizeof(arr[0]);printf("数组元素为:");recursivePrint(arr, size, 0);printf("\n");return 0;
}

2.二叉树的顺序存储表示法和实现

     图1.完全二叉树

               图2.普通二叉树

        我们使用一组连续的存储空间表示树的结构。按照从上到下、从左到右的顺序存储完全二叉树的的节点,对于一般二叉树上的点,我们使用0表示不存在该节点。

        对于图1来说,内存中的存储结构如下图3所示。

        图3.完全二叉树的存储结构

        如果不是二叉树,假如我们使用0表示结点不存在,图2所示的存储结构如图4所示。

图4.普通二叉树

        下面我们看看如果使用代码来实现。

1.定义

        我们使用数组实现二叉树的顺序存储

#define MAX_TREE_SIZE 100typedef char TElemType;
typedef int Status;typedef TElemType SqBiTree[MAX_TREE_SIZE];

2.初始化

        初始化时候,将数组中的元素全部设为"\0"

// 初始化二叉树
Status initSqBiTree(SqBiTree tree) {for (int i = 0; i< MAX_TREE_SIZE; i++) {tree[i] = '\0';}// 将二叉树所有元素初始化为空return 1; // 初始化成功
}

3.先序遍历二叉树

        遍历二叉树之前我们观察下根节点、左子树节点、右子树节点的规律。

        根节点的下标为a[0].左子树上的节点的下标依次为1,3,...2*i+1,右子树上的节点的下标依次为2,4,...2*i+2

// 前序遍历二叉树
void preOrderTraverse(SqBiTree tree, int node_index) {if (node_index < MAX_TREE_SIZE && tree[node_index] != '\0') {// 访问根节点printf("%c ", tree[node_index]);// 递归遍历左子树preOrderTraverse(tree, 2 * node_index + 1);// 递归遍历右子树preOrderTraverse(tree, 2 * node_index + 2);}
}

4.中序遍历二叉树

// 中序遍历二叉树
void inOrderTraverse(SqBiTree tree, int node_index) {if (node_index < MAX_TREE_SIZE && tree[node_index] != '\0') {// 递归遍历左子树inOrderTraverse(tree, 2 * node_index + 1);// 访问根节点printf("%c ", tree[node_index]);// 递归遍历右子树inOrderTraverse(tree, 2 * node_index + 2);}
}

5.后序遍历二叉树

// 后序遍历二叉树
void postOrderTraverse(SqBiTree tree, int node_index) {if (node_index < MAX_TREE_SIZE && tree[node_index] != '\0') {// 递归遍历左子树postOrderTraverse(tree, 2 * node_index + 1);// 递归遍历右子树postOrderTraverse(tree, 2 * node_index + 2);// 访问根节点printf("%c ", tree[node_index]);}
}

6.完整代码

#include <stdio.h>#define MAX_TREE_SIZE 100typedef char TElemType;
typedef int Status;typedef TElemType SqBiTree[MAX_TREE_SIZE];// 初始化二叉树
Status initSqBiTree(SqBiTree tree) {for (int i = 0; i< MAX_TREE_SIZE; i++) {tree[i] = '\0';}// 将二叉树所有元素初始化为空return 1; // 初始化成功
}// 前序遍历二叉树
void preOrderTraverse(SqBiTree tree, int node_index) {if (node_index < MAX_TREE_SIZE && tree[node_index] != '\0') {// 访问根节点printf("%c ", tree[node_index]);// 递归遍历左子树preOrderTraverse(tree, 2 * node_index + 1);// 递归遍历右子树preOrderTraverse(tree, 2 * node_index + 2);}
}// 中序遍历二叉树
void inOrderTraverse(SqBiTree tree, int node_index) {if (node_index < MAX_TREE_SIZE && tree[node_index] != '\0') {// 递归遍历左子树inOrderTraverse(tree, 2 * node_index + 1);// 访问根节点printf("%c ", tree[node_index]);// 递归遍历右子树inOrderTraverse(tree, 2 * node_index + 2);}
}// 后序遍历二叉树
void postOrderTraverse(SqBiTree tree, int node_index) {if (node_index < MAX_TREE_SIZE && tree[node_index] != '\0') {// 递归遍历左子树postOrderTraverse(tree, 2 * node_index + 1);// 递归遍历右子树postOrderTraverse(tree, 2 * node_index + 2);// 访问根节点printf("%c ", tree[node_index]);}
}int main(int argc, const char *argv[]) {SqBiTree tree;// 初始化二叉树initSqBiTree(tree);// 构造一个简单的二叉树,根节点为'A',左子树为'B',右子树为'C'tree[0] = 'A';tree[1] = 'B';tree[2] = 'C';tree[3] = 'D';tree[4] = 'E';tree[5] = '\0';tree[6] = '\0';// 输出初始化后的二叉树printf("前序遍历结果为:");preOrderTraverse(tree, 0);printf("\n");printf("中序遍历结果为:");inOrderTraverse(tree, 0);printf("\n");printf("后序遍历结果为:");postOrderTraverse(tree, 0);printf("\n");return 0;
}// 后序遍历二叉树
void postOrderTraverse(SqBiTree tree, int node_index) {if (node_index < MAX_TREE_SIZE && tree[node_index] != '\0') {// 递归遍历左子树postOrderTraverse(tree, 2 * node_index + 1);// 递归遍历右子树postOrderTraverse(tree, 2 * node_index + 2);// 访问根节点printf("%c ", tree[node_index]);}
}int main(int argc, const char *argv[]) {SqBiTree tree;// 初始化二叉树initSqBiTree(tree);// 构造一个简单的二叉树,根节点为'A',左子树为'B',右子树为'C'tree[0] = 'A';tree[1] = 'B';tree[2] = 'C';tree[3] = 'D';tree[4] = 'E';tree[5] = '\0';tree[6] = '\0';// 输出初始化后的二叉树printf("前序遍历结果为:");preOrderTraverse(tree, 0);printf("\n");printf("中序遍历结果为:");inOrderTraverse(tree, 0);printf("\n");printf("后序遍历结果为:");postOrderTraverse(tree, 0);printf("\n");return 0;
}

        在main函数中,我们构建了一个图2所示的二叉树,控制台打印信息如下:

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

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

相关文章

AUTOSAR OS调度表讲解

调度表 AUTOSAR OS通过调度表(Schedule Table)来解决一个alarm只能激活一个任务的限制。调度表是预定义的行为序列,通过到期点实现。AUTOSAR OS遍历调度表并依次处理每个到期点,遍历由底层的counter来实现驱动。 到期点发生在从概念零开始的静态配置偏移量上。偏移量在静…

【程序设计和c语言-谭浩强配套】(适合专升本、考研)

一晃大半年没更新了&#xff0c;这一年一直在备考&#xff0c;想着这几天把前段时间学的c语言给大家分享一下&#xff0c;在此做了一个专栏&#xff0c;有需要的小伙伴可私信获取o。 简介&#xff1a;本专栏所有内容皆适合专升本、考研的复习资料&#xff0c;本人手上也有日常…

【2024亚马逊云科技峰会】Amazon Bedrock + Llama3 生成式AI实践

在 4 月 18 日&#xff0c;Meta在官网上公布了旗下最新大模型Llama 3。目前&#xff0c;Llama 3已经开放了80亿&#xff08;8B&#xff09;和700亿&#xff08;70B&#xff09;两个小参数版本&#xff0c;上下文窗口为8k&#xff0c;据称&#xff0c;通过使用更高质量的训练数据…

【基础算法总结】二分查找一

二分查找一 1. 二分查找2.在排序数组中查找元素的第一个和最后一个位置3.x 的平方根4.搜索插入位置 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一起努力吧!&#x1f603;&#x1…

制造业数字化转型解决方案及应用(125页PPT)

一、资料介绍 《制造业数字化转型解决方案及应用》是一份内容丰富、深入剖析制造业数字化转型的125页PPT资料。这份资料以“智能制造、制造业数字化转型、制造业数字化转型案例”为关键词&#xff0c;全面展现了制造业数字化转型的核心理念、解决方案以及实际应用案例。 关注…

【JS红宝书学习笔记】第1、2章

第1章 什么是JavaScript JavaScript 是一门用来与网页交互的脚本语言&#xff0c;包含以下三个组成部分。 ECMAScript&#xff1a;由 ECMA-262 定义并提供核心功能。文档对象模型&#xff08;DOM&#xff09;&#xff1a;提供与网页内容交互的方法和接口。浏览器对象模型&…

块元素、内联元素、行内块元素

一、介绍&#xff1a; CSS元素划分成块元素、行内元素&#xff08;内联元素&#xff09;、行内块元素等多种常用类型。也就是说&#xff1a;在CSS中&#xff0c;元素根据其在页面上的布局方式被分为不同的显示类型。 背景&#xff1a;HTML负责定义网页的结构和内容&#xff0c…

OC foudation框架(上)学习

foundation框架 文章目录 foundation框架字符串&#xff08;NSString && NSMutableString&#xff09;NSString的其他功能NSMutableString 日期与时间 &#xff08;NSDate&#xff09;2.1 日期与时间&#xff08;NSDate&#xff09;2.2日期格式器日历与日期组件定时器&…

Java入门基础学习笔记8——注释

1、注释&#xff1a; 注释是写在程序中对代码进行解释说明的文件&#xff0c;方便自己和其他人查看&#xff0c;以便理解程序的。 package cn.ensource.note;/**文档注释文档注释 */ public class NoteDemo {public static void main(String[] args) {// 单行注释System.out.…

word转pdf的java实现(documents4j)

一、多余的话 java实现word转pdf可用的jar包不多&#xff0c;很多都是收费的。最近发现com.documents4j挺好用的&#xff0c;它支持在本机转换&#xff0c;也支持远程服务转换。但它依赖于微软的office。电脑需要安装office才能转换。鉴于没在linux中使用office&#xff0c;本…

SwiftUI 调整视图内容周围间隙(Content Margins)的“时髦”方法

概述 在 SwiftUI 开发的应用中,往往在小屏设备(比如 iPhone)上布局良好的 App 放到大屏(iPad)上后就会“一塌糊涂”。因为它们一味的只想着“占据”却不知道“舍弃”。 从 iOS 17.0(iPad 17.0)开始苹果提供了原生的视图修改器方法专注于处理此事。 在本篇博文中,您将…

windows轻松管理nodejs 版本 升/降级 卸载等等

#nvm-windows 管理nodejs 版本神器# 不经意升级了node版本导致原有项目启动异常, 看到了node版本管理神器:nvm-windos 1,先下载 nvm >> git 选择如下安装包或 nvm-setup.exe文件 https://github.com/coreybutler/nvm-windows/releases/tag/1.1.12 2. 双击安装,下一…

Win10 WSL2 Ubuntu 22.04 配置深度学习环境

文章目录 WSL安装Anaconda下载Anaconda安装包安装配置conda命令conda换国内源conda初始化shell环境conda init手动源激活脚本&#xff1a; 安装Windows上的NVIDIA GPU驱动WSL安装CUDA Toolkit安装12.1版本环境配置报错1报错2 内存不足导致安装崩溃问题描述问题分析问题解决 WSL…

用docker 搭建 vscode for web

前言: 每当我们换机子或者是电脑内容不够的时候&#xff0c;总想着能用web方式使用某些软件&#xff0c;这样子&#xff0c;你无论何时何地都能愉快的开发了&#xff0c;今天来安排下使用容器技术去搭建vscode。 查找合适的Docker镜像 你可以使用官方的Code Server Docker镜像…

vue2人力资源项目6角色管理

elementUi编写表格样式及分页组件 <template><div class"container"><div class"app-container"><!--角色管理内容--><div class"role-operate"><el-button type"primary">添加角色</el-butt…

一键开启,盲盒小程序里的梦幻奇遇

在这个充满惊喜与未知的数字时代&#xff0c;盲盒小程序以其独特的魅力成为了许多人的新宠。只需一键开启&#xff0c;你就能踏入一个充满梦幻奇遇的世界&#xff0c;探索未知的惊喜与乐趣。 盲盒小程序不仅仅是一个简单的购物平台&#xff0c;它更是一个充满神秘与惊喜的宝藏库…

ETL中如何执行Python脚本

Python的解读 Python 是一种高级、通用的编程语言&#xff0c;由荷兰程序员吉多范罗苏姆&#xff08;Guido van Rossum&#xff09;于1990年代初设计并发布。Python的设计哲学强调代码的可读性和简洁性&#xff0c;它的语法清晰且表达力强&#xff0c;使得开发者能够以更少的代…

GT2512-STBA 三菱触摸屏12.1寸型

T2512-STBA参数说明&#xff1a;12.1"、SVGA 800*600、65536色、TFT彩色液晶显示屏、AC电源、32MB内存 三菱触摸屏GT2512-STBA性能规格详细说明&#xff1a; [显示部] 显示软元件&#xff1a;TFT彩色液晶显示屏 画面尺寸&#xff1a;12.1寸 分辨率&#xff1a;SVGA 80…

【Vue】Vue的核心

目录 计算属性-computed插值语法实现methods实现计算属性实现使用使用总结&#xff1a; 监视属性-watch监视的两种写法&#xff1a;深度监视备注&#xff1a; computed和watch之间的区别 绑定样式class样式绑定字符串写法数组写法对象写法 style样式绑定对象式1对象式2数组式 条…

Web数字孪生引擎

Web数字孪生引擎是指用于在Web上创建和运行数字孪生的软件平台。它们通常提供一组API和工具&#xff0c;用于连接到实时数据源、可视化数据并创建交互式体验。Web数字孪生引擎被广泛应用于各种应用&#xff0c;例如工业物联网、智能建筑、城市管理和公共安全等。北京木奇移动技…