做旅游网站的开题报告/百度视频

做旅游网站的开题报告,百度视频,苏州比较好的建筑公司,wordpress 4.9.6 zh目录 1.概念与结构 2.二叉数链式的实现 2.1遍历规则 2.2申请内存空间 2.3手动构建一棵二叉树 2.4二叉树结点的个数 2.5二叉树叶子结点的个数 2.6二叉树第K层结点个数 2.7二叉树的高度 2.8二叉树中查找值为x的结点 2.9二叉树的销毁 3.层序遍历 3.1概念 3.2层序遍历…

目录

1.概念与结构

2.二叉数链式的实现

2.1遍历规则

2.2申请内存空间

2.3手动构建一棵二叉树

2.4二叉树结点的个数

2.5二叉树叶子结点的个数

2.6二叉树第K层结点个数

2.7二叉树的高度

2.8二叉树中查找值为x的结点

2.9二叉树的销毁

3.层序遍历

3.1概念

3.2层序遍历的实现

4.判断是否为完全二叉树

5.总结


1.概念与结构

用链表来表示一棵二叉树,即用链表来指示元素的逻辑关系。通常的方法是链表中每一个由三个域组成:数据域,左指针域和右指针域。左右指针分别用来给出该结点的左孩子和右孩子所在的链结点的存储地址,最终结点的结构是下面所示:

typedef int BTDataType;
typedef struct BinaryTreeNode
{
    BTDataType data;
    struct BinaryTreeNode* left;
    struct BinaryTreeNode* right;
}BTNode;

由于根结点的左子树分别又是由子树结点、子树结点的左子树、子树结点的右子树组成的。因此二叉树定义是递归式的,链式二叉树的操作中基本都是按照该概念实现的。所以我们在二叉树的各种操作中都要用到递归操作,所以代码比较简单,但是比较难写出来!

2.二叉数链式的实现

2.1遍历规则

(1)前序遍历

访问根结点的操作发生在左右结点之前,即我们先遍历更结点然后再是左结点,最后才是右结点。

我们从A开始进入二叉树,先打印A结点的数据,再打印A结点的左孩子即为B,再同理推出D,由于D的左孩子为NULL,打印完NULL后再进入D的右孩子,又为NULL,然后返回到B ,B 的左孩子已经打印完了,所以我们开始打印B的右孩子,由于为NULL,所以我们返回到B,B 子树已经全部遍历完了,所以我们开始遍历C 子树,以此类推,最终打印出顺序为:ABDNULLNULLNULLCENULLNULLFNULLNULL这就是我们所说的前序遍历。

代码实现:

//前序遍历
void PreOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}printf("%c", root->data);//我们主要是打印出这个结点的位置,所以我们用字母来表示这个//我们要把开始typedef的int 改为charPreOrder(root->left);PreOrder(root->right);
}

(2)中序遍历

中序遍历是先从左结点开始遍历后面是根结点最后是右结点。容易知道上副图的遍历结果为ABDNULLNULLNULLCENULLNULLFNULLNULL,所以最终代码实现是:

//中序遍历
void InOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}InOrder(root->left);printf("%c ", root->data);InOrder(root->right);
}

(3)后序遍历

后序遍历是先去遍历左结点,再是右结点最后才是根结点,所以开始的运行结果为NULL NULL D NULL B NULL NULL E NULL NULL F C A,代码实现:

//后序遍历
void PostOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}PostOrder(root->left);PostOrder(root->right);printf("%c ", root->data);
}

2.2申请内存空间

我们需要先malloc一个结点大小的空间并且把传入的数据赋值给data,左孩子和右孩子指针置为NULL,所以代码如下:

//申请内存空间
BTNode* buyNode(BTDataType x)
{BTNode* node = (BTNode*)malloc(sizeof(BTNode));node->data = x;node->left = node->right = NULL;
}

2.3手动构建一棵二叉树

我们如果和我们之前的那张图片一样构造二叉树的结果一样的话,我们可以写出以下代码:

//手动构造一块二叉树
BTNode* CreateTree()
{BTNode* nodeA = buyNode('A');BTNode* nodeB = buyNode('B');BTNode* nodeC = buyNode('C');BTNode* nodeD = buyNode('D');BTNode* nodeE = buyNode('E');BTNode* nodeF = buyNode('F');nodeA->left = nodeB;nodeA->right = nodeC;nodeB->left = nodeD;nodeC->left = nodeE;nodeC->right = nodeF;return nodeA;
}

2.4二叉树结点的个数

我们发现二叉树结点个数等于左子树的结点个数加上右结点个数加上根结点的个数(1)构成,而左子树也等于左二叉树的结点个数加上右二叉树的结点个数加上根结点的个数(1)构成,所以最终代码如下:

//二叉树结点个数
int BinaryTreeSize(BTNode* root)
{if (root == NULL){return 0;}return BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

2.5二叉树叶子结点的个数

我们发现二叉树叶子结点的个数=左子树叶子结点的个数+右子树叶子结点的个数,所以最终代码如下:

//叶子结点的个数
int BinaryTreeLeafSize(BTNode* root)
{if (root == NULL){return 0;}if (root->left == NULL && root->right == NULL){return 1;}return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}

2.6二叉树第K层结点个数

我们发现二叉树第K层结点个数=左子树第K层结点的个数+右子树第K层结点的个数,所以最终代码如下:

//二叉树第K层结点个数
int BinaryTreeLevelKSize(BTNode* root, int k)
{if (root == NULL){return 0;}if (k == 1){return 1;}return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);
}

2.7二叉树的高度

我们要比较的是左子树深度和右子树的深度,比较大的一方才算,即为根结点+max(左子树,右子树)我们先调用一下左子树的递归序列,并把左子树的深度存储起来,然后把右子树按照同样的方法进行存储,后面返回其中最大的一个加1即可,最终代码如下:

//求二叉树的深度
int BinaryTreeDepth(BTNode* root)
{if (root == NULL){return 0;}int leftDep = BinaryTreeDepth(root->left);int rightDep = BinaryTreeDepth(root->right);return 1 + (leftDep > rightDep ? leftDep : rightDep);
}

2.8二叉树中查找值为x的结点

我们用前序遍历方法进行查找,代码如下:

//二叉树中查找值为x的结点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{if (root == NULL){return NULL;}if (root->data == x){return root;}BTNode* leftFind = BinaryTreeFind(root->left, x);if (leftFind){return leftFind;}BTNode* rightFind = BinaryTreeFind(root->right, x);if (rightFind){return rightFind;}return NULL;
}

2.9二叉树的销毁

我们需要传一个指针,然后先进行左子树的销毁,最后再进行右子树的销毁,所以代码如下:

//二叉树的销毁
void BinaryTreeDestory(BTNode** root)
{if (*root == NULL){return;}BinaryTreeDestory(&(*root)->left);//->的优先级大于*BinaryTreeDestory(&(*root)->right);free(*root);*root = NULL;
}

3.层序遍历

3.1概念

层序遍历就是从二叉树的根结点出发,依次往左孩子到右孩子进行访问,像我们上一副图的层序遍历就是ABCDEF。

3.2层序遍历的实现

先说结论,我们用队列来实现层序遍历,先进行根结点入队列,若发现不为空,则把队头数据进行出队操作,若取出的结点有左孩子(右孩子),则把左孩子(右孩子)入队列,依次类推。所以我们需要队列这个数据结构的帮助。我们把之前的代码复制过来有

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>
#include<stdbool.h>
//定义队列结点的结构
typedef int STDataType;
typedef struct QueueNode
{STDataType data;struct QueueNode* next;
}QueueNode;
//队列的结构
typedef struct Queue
{QueueNode* phead;QueueNode* ptail;
}Queue;
//队列的初始化
void QueueInit(Queue* pq)
{assert(pq);//防止传参为空pq->phead = pq->ptail = NULL;
}
//入队列
void QueuePush(Queue* pq, STDataType x)
{assert(pq);QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));if (newnode == NULL){perror("malloc fail!\n");exit(1);}newnode->data = x;newnode->next = NULL;if (pq->phead == NULL){//也可以写为//pq->phead==pq->ptailpq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;//也可以把pq->ptail=newnode写到if-else语句之后}
}
//队列判空
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->phead == NULL;
}
//队列有效元素的个数
int QueueSize(Queue* pq)
{int size = 0;QueueNode* pcur = pq->phead;while (pcur){size++;pcur = pcur->next;}return size;
}
//出队列
void QueuePop(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));if (pq->phead == pq->ptail){free(pq->phead);pq->phead = pq->ptail = NULL;}else{QueueNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}
}
//取队头数据
STDataType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->phead->data;
}
//取队尾数据
STDataType QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->ptail->data;
}
//销毁队列
void QueueDestroy(Queue* pq)
{assert(pq);QueueNode* pcur = pq->phead;while (pcur){QueueNode* next = pcur->next;free(pcur);pcur = next;}pq->phead = pq->ptail = NULL;//可以加pq->size=0
}
//测试函数
void test()
{Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);int size = QueueSize(&q);printf("%d\n", size);QueuePop(&q);size = QueueSize(&q);printf("%d\n", size);size = QueueFront(&q);printf("%d\n", size);size = QueueBack(&q);printf("%d\n", size);QueueDestroy(&q);
}
int main()
{test();return 0;
}

我们需要改以下的东西:typedef struct BiaryTreeNode*  STDataType;(我们所存储的数据类型是struct BinaryTreeNode*),之所以是指针,因为我们之后要使用二级指针,这样子更方便,所以最终实现有:

//层序遍历
void LevelOrder(BTNode* root)
{Queue q;QueueInit(&q);QueuePush(&q, root);while (!QueueEmpty(&q)){BTNode* top = QueueFront(&q);QueuePop(&q);printf("%c ", top->data);if (top->left){QueuePush(&q, top->left);}if (top->right){QueuePush(&q, top->right);}}QueueDestroy(&q);
}

4.判断是否为完全二叉树

完全二叉树有两个特点:除最后一层外其余层数的结点个数都达到最大;最后一层结点从左到右依次排列。代码实现如下(我会注释):

//判断是否为完全二叉树
bool BinaryTreeComplete(BTNode* root)
{Queue q;QueueInit(&q);QueuePush(&q, root);while (!QueueEmpty(&q)){//取队头出队头BTNode* top = QueueFront(&q);QueuePop(&q);if (top == NULL){break;}//把不为空的队头结点的左右孩子入队列QueuePush(&q, top->left);QueuePush(&q, top->right);}//队列不一定为空,继续取队头出队头while (!QueueEmpty(&q)){BTNode* top = QueueFront(&q);QueuePop(&q);if (top != NULL){QueueDestroy(&q);return false;}}QueueDestroy(&q);return true;
}

5.总结

二叉树链式代码比较简单,但是实现这个比较难。下节我将讲解二叉树的应用,喜欢的可以一键三连哦。

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

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

相关文章

鸿蒙HarmonyOS NEXT之无感监听

鸿蒙中存在一些无感监听&#xff0c;这些监听经过系统API封装使用很简单&#xff0c;但是对实际业务开发中有很重要&#xff0c;例如埋点业务、数据统计、行为上报、切面拦截等。 Navigation的页面切换 在鸿蒙中Navigation被用来作为路由栈进行页面跳转&#xff0c;如果你想知…

批量处理word里面表格的空白行

1&#xff0c;随便打开一个word文档。 2&#xff0c;按下Alt F11 VBA编辑器,在左侧的「工程资源管理器」窗口中找到Normal 项目,右键选择插入->模块。 弹出一下弹窗 3&#xff0c;输入一下代码 代码&#xff1a; Sub RemoveEmptyTableRows()Dim tbl As TableDim row As R…

3ds Max 2026 新功能全面解析

一、视口性能与交互体验升级 1. Hydra 2.0 视口渲染引擎 3ds Max 2026 引入了 Hydra 2.0&#xff0c;大幅优化了视口渲染性能&#xff0c;尤其是在处理复杂场景和高质量实时预览时&#xff0c;流畅度提升显著。 支持USD&#xff08;通用场景描述&#xff09;格式&#xff0c…

JVM垃圾回收笔记02-垃圾回收器

文章目录 前言1.串行(Serial 收集器/Serial Old 收集器)Serial 收集器Serial Old 收集器相关参数-XX:UseSerialGC 2.吞吐量优先(Parallel Scavenge 收集器/Parallel Old 收集器)Parallel Scavenge 收集器Parallel Old 收集器相关参数-XX:UseParallelGC ~ -XX:UseParallelOldGC-…

使用AI一步一步实现若依(26)

功能26&#xff1a;新增一个新员工培训页面 功能25&#xff1a;角色管理 功能24&#xff1a;菜单管理 功能23&#xff1a;从后端获取路由/菜单数据 功能22&#xff1a;用户管理 功能21&#xff1a;使用axios发送请求 功能20&#xff1a;使用分页插件 功能19&#xff1a;集成My…

vue响应式原理剖析

一、什么是响应式? 我们先来看一下响应式意味着什么?我们来看一段代码: m有一个初始化的值,有一段代码使用了这个值; 那么在m有一个新的值时,这段代码可以自动重新执行; let m = 20 console.log(m) console.log(m * 2)m = 40上面的这样一种可以自动响应数据变量的代码机…

无人机航电系统电池技术解析!

1. 常用电池类型 锂聚合物电池&#xff08;LiPo&#xff09; 特点&#xff1a;高能量密度、轻量化、放电效率高&#xff0c;是目前主流选择。 缺点&#xff1a;对过充/过放敏感&#xff0c;需严格管理&#xff0c;存在轻微膨胀或起火风险。 锂离子电池&#xff08;Li-ion…

ubuntu下终端打不开的排查思路和解决方法

问题现象描述&#xff1a;ubuntu开机后系统桌面显示正常&#xff0c;其他图形化的app也都能打开无异常&#xff0c;唯独只有terminal终端打不开&#xff0c;无论是鼠标点击终端软件&#xff0c;还是ctrlaltt&#xff0c;还是altF2后输入gnome-terminal后按回车&#xff0c;这三…

Maven入门

1、简介 Apache Maven是一个项目管理及自动构建工具&#xff0c;由Apache软件基金会所提供。基于项目对象模型&#xff08;缩写&#xff1a;POM&#xff09;概念&#xff0c;Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。 2、作用 1&#xff09;依赖导…

Rk3588,Opencv读取Gmsl相机,Rga yuv422转换rgb (降低CPU使用率)

RK3588, 使用OpenCv 读取 gmsl 相机,获得yuv422格式图像, 使用 rga 转换 rgb 图像。减少cpu占用率. 查看相机信息 v4l2-ctl --all -d /dev/cam0 , 查看自己相机分辨率,输出格式等信息,对应修改后续代码测试… Driver Info:Driver name : rkcifCard type : rkc…

【NLP 49、提示工程 prompt engineering】

目录 一、基本介绍 语言模型生成文本的基本特点 提示工程 prompt engineering 提示工程的优势 使用注意事项 ① 安全问题 ② 可信度问题 ③ 时效性与专业性 二、应用场景 能 ≠ 适合 应用场景 —— 百科知识 应用场景 —— 写文案 应用场景 —— 解释 / 编写…

SpringCould微服务架构之Docker(3)

1&#xff09;什么是镜像和容器&#xff1f; 2&#xff09;DockerHub&#xff1a; 3&#xff09;docker的架构如下&#xff1a;

智慧高速,安全护航:视频监控平台助力高速公路高效运营

随着我国高速公路里程的不断增长&#xff0c;交通安全和运营效率面临着前所未有的挑战。传统的监控方式已难以满足现代化高速公路管理的需求&#xff0c;而监控视频平台的出现&#xff0c;则为高速公路的安全运营提供了强有力的技术支撑。高速公路视频监控联网解决方案 高速公路…

AI 在测试中的应用:从自动化到智能化的未来

阅读原文 在上一篇中&#xff0c;我们探讨了测试左移与右移如何构建质量保障的全流程闭环。现在&#xff0c;我们将目光投向更前沿的领域——AI在测试中的应用。这不仅是技术的演进&#xff0c;更是测试理念的革命&#xff1a;从"自动化执行"到"智能决策"…

# 使用自定义Shell脚本hello快速配置Linux用户账户

使用自定义Shell脚本快速配置Linux用户账户 在学校实验室管理Linux服务器&#xff0c;或者公司小团队管理服务器时&#xff0c;大家需要一个能隔离自己服务&#xff0c;但是自己又需要对服务器的完整权限的情形。创建和配置用户账户是一项常见但繁琐的任务。特别是当你需要频繁…

Unity Animation的其中一种运用方式

Animation是Unity的旧的动画系统&#xff0c;先说目的&#xff0c;其使用是为了在UI中播放动效&#xff0c;并且在动效播放结束后接自定义事件而设计的 设计的关键点在于&#xff0c;这个脚本不是通过Animation直接播放动画片段&#xff0c;而是通过修改AnimationState的nor…

matplotlib——南丁格尔玫瑰

南丁格尔玫瑰图&#xff08;Nightingale Rose Chart&#xff09;&#xff0c;是一种特殊形式的柱状图&#xff0c;它以南丁格尔&#xff08;Florence Nightingale&#xff09;命名&#xff0c;她在1858年首次使用这种图表来展示战争期间士兵死亡原因的数据。 它将数据绘制在极坐…

6.go语言函数

Go语言中的函数是组织代码的最小单元&#xff0c;用于封装一段代码&#xff0c;完成特定的功能。函数的使用可以减少代码冗余&#xff0c;提高代码的可读性和可维护性。 函数的基本定义和语法 在Go语言中&#xff0c;定义一个函数的基本语法如下&#xff1a; func functionN…

SpringCould微服务架构之Docker(4)

Docker ce是社区版。 安装docker之前&#xff0c;先安装yum-util 。 安装docker之前&#xff0c;一定要先关闭防火墙。

Keepalived 实现高可用方案

Keepalived简介 ‌Keepalived‌ 是一个基于 ‌VRRP&#xff08;Virtual Router Redundancy Protocol&#xff09;协议‌的高可用性解决方案&#xff0c;主要用于实现‌服务故障自动切换&#xff08;Failover&#xff09;和负载均衡‌。通过管理虚拟 IP&#xff08;VIP&#xf…