1. ​​树数据结构的基本定义和属性​

树是一种重要的非线性数据结构,用于表示层次关系。

  • ​基本定义​​:树是由 n(n ≥ 0)个结点组成的有限集合。当 n = 0 时,称为空树;当 n > 0 时,树必须满足两个条件:
    • 有且仅有一个特定的根结点(root node)。
    • 当 n > 1 时,其余结点可划分为 m(m > 0)个互不相交的子集 T1, T2, ..., Tm,每个子集本身又是一棵树,称为子树(subtree)。
  • ​结点属性​​:
    • ​结点的度(degree)​​:指一个结点拥有的子树个数。例如,一个结点有 3 个子树,则其度为 3。
    • ​叶结点(leaf node)​​:度为 0 的结点,即没有子树的结点。
    • ​分支结点(branch node)​​:度不为 0 的结点,即至少有一个子树的结点。
  • ​树的整体属性​​:
    • ​树的度数​​:指树中所有结点的度的最大值。例如,如果所有结点度的最大值为 3,则树的度数为 3。
    • ​树的深度或高度​​:从根结点开始计算,根所在层为第 1 层,其子结点为第 2 层,依此类推。深度反映了树的层级结构。
  • ​树的性质强调​​:树的结构强调“互不相交”的子集,确保每个结点只属于一个父结点,避免循环或重复。

2. ​​树的存储结构​

  • ​顺序结构​​:将树结点存储在连续的内存位置(如数组),通过索引表示父子关系。优点是访问快速,但插入/删除操作可能低效。
  • ​链式结构​​:使用指针或引用来链接结点(如链表),每个结点包含数据域和指向子树的指针。优点是灵活,适用于动态树结构。


3. ​​二叉树的定义和类型​

二叉树是树的特例,具有严格的子树顺序规则。

  • ​基本定义​​:二叉树是 n 个结点的有限集合,它要么为空树,要么由一个根结点和两棵互不相交的左子树与右子树组成。关键特点包括:
    • 每个结点最多有两个子树(左子树和右子树)。
    • 左子树和右子树有固定顺序,不能颠倒(例如,交换左右子树会改变树结构)。
    • 如果结点只有一个子树,必须明确指定是左子树或右子树。
  • ​特殊二叉树类型​​:
    • ​斜树(skewed tree)​​:所有结点都只有左子树(左斜树)或只有右子树(右斜树)。结构类似线性链表。
    • ​满二叉树(full binary tree)​​:所有分支结点都有左右子树,且所有叶结点都在同一层上。结点总数达到最大值(2^k - 1,k 为深度)。
    • ​完全二叉树(complete binary tree)​​:对树按层序编号(根为 1),每个结点的编号与同深度的满二叉树中对应结点位置相同。不完全二叉树在编号上会有空缺。

4. ​​二叉树的数学特性和遍历方法​

  • ​数学特性​​:
    • 第 i 层(i ≥ 1)最多有 2^(i-1) 个结点。
    • 深度为 k 的二叉树(k ≥ 1)最多有 2^k - 1 个结点。
    • 关键公式:对于任意二叉树,叶子结点数(n0)和度为 2 的结点数(n2)满足 n0 = n2 + 1。
    • 对于有 n 个结点的完全二叉树,深度为 (log₂(n)) + 1。
  • ​遍历方法​​:遍历是访问树中所有结点的过程,三种主要顺序:
    • ​前序遍历(preorder traversal)​​:顺序为“根-左-右”。先访问根结点,然后递归访问左子树,最后右子树。
    • ​中序遍历(inorder traversal)​​:顺序为“左-根-右”。从根开始但不先访问根;先递归访问左子树,再访问根,最后右子树。常用于二叉搜索树(BST)。
    • ​后序遍历(postorder traversal)​​:顺序为“左-右-根”。从根开始但不先访问根;先递归访问左子树,然后右子树,最后根。
    • ​层序遍历(level order traversal)​​:按层从上到下、从左到右访问结点。
      遍历方法强调递归实现,适用于树结构的递归特性。

5. ​​GDB调试工具的常规使用步骤​

GDB(GNU Debugger)的实用指南,用于调试C/C++程序,特别是处理段错误和一般调试:

  • ​调试段错误(segmentation fault)​​:
    1. 编译时添加调试选项:使用 gcc -g *.c 生成带调试信息的可执行文件。
    2. 启动GDB:运行 gdb a.out
    3. 运行程序:在GDB中输入 r(run)命令执行程序。
    4. 重现错误:让程序运行到崩溃点。
    5. 定位错误:输入 wherebt 命令显示调用栈,找出段错误发生的具体位置(如文件和行号)。
  • ​一般调试流程​​:
    1. 设置断点:使用 b 命令(break),例如 b fun.c:36 在文件 fun.c 的第 36 行设置断点,或 b myfun 在函数 myfun 入口处设断点。
    2. 运行程序:输入 r 开始执行,程序会在断点处暂停。
    3. 单步执行:
      • n(next):步过,执行下一行代码(如果遇到函数,不进入函数内部)。
      • s(step):步入,执行下一行代码(如果遇到函数,进入函数内部)。
    4. 查看变量:使用 p(print)命令,例如 p a 显示变量 a 的值,或 p *ptr 显示指针 ptr 指向的数据。display a 可持续显示变量变化。
    5. 控制执行:
      • c(continue):从当前断点继续运行,直到下一个断点或程序结束。
      • return:强制从当前函数返回调用处。
    6. 辅助命令:set print elements 300 设置字符串显示长度(避免截断)。
  • ​关键优势​​:GDB 能通过 where 命令追踪函数调用栈,帮助快速定位内存错误或逻辑问题。

6. ​​希尔排序算法​

  • ​算法原理​​:希尔排序通过分组比较和插入来优化排序。它使用一个“间隙”(gap)序列,初始 gap 为数组长度的一半,逐步减小 gap 至 1(此时等价于插入排序)。核心是减少逆序对,提升效率。
  • ​代码实现​​:
    void shell_sort(int a[], int len) 
    {for (int gap = len / 2; gap > 0; gap /= 2) {  // gap 从 len/2 开始,每次减半for (int i = gap; i < len; ++i) // 从 gap 位置开始遍历{         int temp = a[i];                      // 保存当前元素int j = i;while (j >= gap && a[j - gap] > temp) { // 比较并移动元素a[j] = a[j - gap];                // 将较大元素后移j -= gap;                         // 跳转到前一个 gap 位置}a[j] = temp;                          // 插入 temp 到正确位置}}
    }
  • ​关键步骤​​:
    1. ​外层循环​​:控制 gap 值(gap = len/2, gap/2, ..., 1)。
    2. ​内层循环​​:对每个 gap 组进行插入排序。从索引 gap 开始,将元素与同组前驱比较,移动元素以保持有序。
    3. ​效率​​:希尔排序平均时间复杂度为 O(n log n),优于简单插入排序 O(n²),适用于中等规模数据。
  • ​应用场景​​:常用于嵌入式系统或内存受限环境,因代码简洁高效。

代码实现:

1.创建数

2.三种遍历方法

3.以队列形式遍历

4..摧毁树

头文件

#ifndef _TREE_H_
#define TREE_H_typedef char DATATYPE;
typedef struct BiTNode /* 结点结构 */
{DATATYPE data;                   /* 结点数据 */struct BiTNode *lchild, *rchild; /* 左右孩子指针 */
} BiTNode;//定义队列节点结构
typedef struct QueueNode 
{// 指向树节点的指针BiTNode *treeNode;// 指向下一个队列节点struct QueueNode *next;
} QueueNode;//定义队列结构
typedef struct Queue 
{// 队列头部QueueNode *head;// 队列尾部QueueNode *tail;
} Queue;extern void CreateTree(BiTNode **root);
extern void PreOrderTraverse(BiTNode *root);
extern void InOrderTraverse(BiTNode *root);
extern void PostOrderTraverse(BiTNode *root);
extern void DestroyTree(BiTNode *root); extern int isQueueEmpty(Queue *queue);
extern void enqueue(Queue *queue, BiTNode *treeNode);
extern BiTNode* dequeue(Queue *queue);
extern void each_of_tree(BiTNode *root);
extern void initQueue(Queue *queue);
#endif

函数

#include <stdio.h>
#include "tree.h"
#include <stdlib.h>char data[] = "Abd#g###ce#h##fi###";
int ind = 0;void CreateTree(BiTNode **root)
{char c = data[ind++];if ('#' == c){*root = NULL;return;}else{*root = malloc(sizeof(BiTNode));if (NULL == *root)               /*判断申请是否成功*/{printf("malloc error\n");*root = NULL;return;}  (*root)->data = c;CreateTree(&(*root)->lchild);    /*左*/CreateTree(&(*root)->rchild);    /*右*/}return;
}
//根左右(前序)
void PreOrderTraverse(BiTNode *root)
{if (NULL == root){return;}else{printf("%c", root->data);PreOrderTraverse(root->lchild);PreOrderTraverse(root->rchild);}return;
}
//左根右(中序)
void InOrderTraverse(BiTNode *root)
{if (NULL == root){return;}InOrderTraverse(root->lchild);printf("%c", root->data);InOrderTraverse(root->rchild);return;
}
//左右根(后序)
void PostOrderTraverse(BiTNode *root)
{if (NULL == root){return;}PostOrderTraverse(root->lchild);PostOrderTraverse(root->rchild);printf("%c", root->data);return;
}
void DestroyTree(BiTNode *root)
{if (NULL == root){return;}DestroyTree(root->lchild);DestroyTree(root->rchild);free(root);root = NULL;return;
}// 初始化队列
void initQueue(Queue *queue) 
{queue->head = queue->tail = NULL;
}//  判断队列是否为空
int isQueueEmpty(Queue *queue) 
{return queue->head == NULL;
}// 入队
void enqueue(Queue *queue, BiTNode *treeNode) 
{QueueNode *newNode = malloc(sizeof(QueueNode));newNode->treeNode = treeNode;newNode->next = NULL;if (isQueueEmpty(queue)) {queue->head = queue->tail = newNode;} else {queue->tail->next = newNode;queue->tail = newNode;}
}// 出队
BiTNode* dequeue(Queue *queue) 
{if (isQueueEmpty(queue)) {return NULL;}QueueNode *temp = queue->head;BiTNode *treeNode = temp->treeNode;queue->head = queue->head->next;if (queue->head == NULL) {queue->tail = NULL;}free(temp);return treeNode;
}// 层序遍历
void each_of_tree(BiTNode *root) 
{if (root == NULL) {return;}//定义对联Queue queue;// 初始化队列initQueue(&queue);// 根节点入队enqueue(&queue, root);while (!isQueueEmpty(&queue)) {// 出队BiTNode *current = dequeue(&queue);//访问节点printf("%c \n", current->data);// 左子节点入队if (current->lchild != NULL) {enqueue(&queue, current->lchild);}// 右子节点入队if (current->rchild != NULL) {enqueue(&queue, current->rchild);}}
}

主函数

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "tree.h"int main(int argc, char **argv)
{BiTNode *root;CreateTree(&root);PreOrderTraverse(root);printf("\n");InOrderTraverse(root);printf("\n");PostOrderTraverse(root);printf("\n");DestroyTree(root);root = NULL;each_of_tree(root);return 0;
}

7. ​​整体总结​

  • ​数据结构核心​​:树和二叉树的定义、属性、存储及遍历是重点,强调树的结构特性(如度、深度)和二叉树的具体规则(如左右子树顺序)。数学特性(如结点数量公式)和遍历方法(前序、中序、后序)为算法实现奠定基础。
  • ​实用工具​​:GDB 调试部分提供 step-by-step 指南,解决段错误和一般调试问题,突出命令如 wherebp 的重要性。
  • ​算法应用​​:希尔排序作为高效排序算法,以代码示例展示其 gap 策略和插入优化。

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

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

相关文章

sqlite的sql语法与技术架构研究

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu) 参考&#xff1a;参考提示词与豆包AI交互输出内容。 sqlite作为最常用的本地数据库&#xff0c;其支持的sql语法也比较全面&#xff0c;历经了二十多年经久不衰&#xff0c;其技术架构设计也是非常优秀的。 一&#xff1a…

Javascript中的一些常见设计模式

1. 单例模式&#xff08;Singleton Pattern&#xff09; 核心思想 一个类只能有一个实例&#xff0c;并提供一个全局访问点。 场景 全局缓存Vuex / Redux 中的 store浏览器中的 localStorage 管理类 示例 const Singleton (function () {let instance;function createInstance…

2025 年最佳 AI 代理:工具、框架和平台比较

目录 什么是 AI Agents 应用 最佳 AI Agents&#xff1a;综合列表 LangGraph AutoGen CrewAI OpenAI Agents SDK Google Agent Development Kit (ADK) 最佳no-code和open-source AI Agents Dify AutoGPT n8n Rasa BotPress 最佳预构建企业 AI agents Devin AI …

Linux 学习 ------Linux 入门(上)

Linux 是一种自由和开放源代码的类 Unix 操作系统。它诞生于 1991 年&#xff0c;由芬兰程序员林纳斯・托瓦兹&#xff08;Linus Torvalds&#xff09;发起并开发。与 Windows 等闭源操作系统不同&#xff0c;Linux 的源代码是公开的&#xff0c;任何人都可以查看、修改和传播&…

[202403-E]春日

[202403-E]春日 题目背景 春水初至&#xff0c; 文笔亦似花开。 题目描述 坐看万紫千红&#xff0c; 提笔洋洋洒洒&#xff0c; 便成篇文章。 现在给你这篇文章&#xff0c; 这篇文章由若干个单词组成&#xff0c; 没有标点符号&#xff0c; 两两单词之间由一个空格隔开。 为了…

Unity笔记(三)——父子关系、坐标转换、Input、屏幕

写在前面写本系列的目的(自用)是回顾已经学过的知识、记录新学习的知识或是记录心得理解&#xff0c;方便自己以后快速复习&#xff0c;减少遗忘。这里只有部分语法知识。九、父子关系1、获取、设置父对象(1)获取父对象可以通过this.transform.parent获取当前对象的父对象Trans…

基于Dubbo的高并发服务治理与流量控制实战指南

基于Dubbo的高并发服务治理与流量控制实战指南 在微服务架构的大规模应用场景中&#xff0c;如何保证服务在高并发压力下的稳定与可用&#xff0c;是每位后端开发者必须面对的挑战。本文结合实际生产环境经验&#xff0c;分享基于Apache Dubbo的高并发服务治理与流量控制方案&a…

Mac 洪泛攻击笔记总结补充

一、Mac 洪泛攻击原理交换机依靠 MAC 地址表来实现数据帧的精准转发&#xff0c;该表记录着端口与相连主机 MAC 地址的对应关系。交换机具备自动学习机制&#xff0c;当收到一个数据帧时&#xff0c;会将帧中的源 MAC 地址与进入的端口号记录到 MAC 表中。同时&#xff0c;由于…

路由器不能上网的解决过程

情况 前段时间&#xff0c;公司来人弄了一下网络后&#xff0c;我的路由器就不能上网了&#xff0c;怎么回事啊。 先看看路由器的情况&#xff1a;看着网络是有连接的&#xff1a;看这上面是能上网的&#xff0c;但是网都是上不去。 奇怪&#xff01; 路由器介绍 路由器&#x…

Rancher 和 KubeSphere对比

以下是 Rancher 与 KubeSphere 的深度对比&#xff0c;涵盖核心定位、架构设计、功能模块、适用场景等关键维度&#xff0c;助您精准选型&#xff1a;一、核心定位与设计哲学维度RancherKubeSphere本质Kubernetes 多集群管理控制平面Kubernetes 全栈云原生操作系统目标简化K8s集…

【深度学习新浪潮】TripoAI是一款什么样的产品?

TripoAI是由硅谷AI初创公司VAST开发的多模态3D内容生成平台,其核心技术基于数十亿参数的3D基础模型,专注于通过文本描述、单图/多图输入或手绘涂鸦快速生成高精度可编辑的3D模型。以下是其核心信息: 一、技术架构与核心功能 秒级生成与多模态输入 生成速度:仅需8秒即可生成…

二十八天(数据结构:图的补充)

图&#xff1a;是一种非线性结构形式化的描述: G{V,R}V:图中各个顶点元素(如果这个图代表的是地图&#xff0c;这个顶点就是各个点的地址)R:关系集合&#xff0c;图中顶点与顶点之间的关系(如果是地图&#xff0c;这个关系集合可能就代表的是各个地点之间的距离)在顶点与顶点…

户外广告牌识别准确率↑32%:陌讯多模态融合算法实战解析

原创声明本文为原创技术解析&#xff0c;核心技术参数与架构设计引用自《陌讯技术白皮书》&#xff0c;禁止任何形式的转载与抄袭。一、行业痛点&#xff1a;户外广告牌识别的三大技术瓶颈户外广告牌作为城市视觉符号的重要载体&#xff0c;其智能化识别在商业监测、合规监管等…

【vue组件通信】一文了解组件通信多种方式

前言 在 Vue 中&#xff0c;组件通信有多种方式&#xff0c;适用于不同场景&#xff08;父子组件、兄弟组件、跨级组件等&#xff09;。以下是完整的组件传值方法总结&#xff0c;仅供概览参考&#xff1a;一、父子组件通信 1. Props&#xff08;父 → 子&#xff09; 父组件通…

项目一系列-第3章 若依框架入门

第3章 若依框架入门 3.1 若依框架概述 为什么要基于若依框架开发&#xff1f; 快速开发&#xff1a;能快速搭建一个应用框架&#xff0c;减少工作量。可定制化&#xff1a;提供丰富插件和拓展点&#xff0c;满足不同项目的特定需求。简化开发流程&#xff1a;框架提供常用的功能…

WSL安装MuJoco报错——FatalError: gladLoadGL error

文章目录WSL中配置MuJoCo报错 FatalError: gladLoadGL error 的终极解决方案&#x1f50d; 问题原因分析✅ 解决方案&#xff1a;切换至 EGL 渲染后端第一步&#xff1a;安装系统级依赖库第二步&#xff1a;使用 Conda 安装兼容的图形库第三步&#xff1a;设置环境变量以启用 E…

2025产品经理接单经验分享与平台汇总

产品和开发永远是一家&#xff0c;如此说来产品和开发接单的经验和平台其实大差不差&#xff0c;今天刚好看到后台有人咨询产品经理接单的问题&#xff0c;索性直接写一篇文章好了。 目录 一、产品经理接单的三个关键建议 1、能力产品化&#xff0c;比履历更重要 2、合同、…

BGP协议笔记

一、BGP协议&#xff08;边界网关协议&#xff09; 是一种用于自治系统间的动态路由协议&#xff0c;是一种外部网关(EGP)协议。负责在不同自治系统(AS)之间交换路由信息&#xff0c;目的是实现大规模网络的可扩展性、策略控制和稳定性。 自治系统AS&#xff1a;一组被进行统…

Ⅹ—6.计算机二级综合题27---30套

第27套 【填空题】 给定程序中,函数fun的功能是:计算形参x所指数组中N个数的平均值(规定所有数均为正数),将所指数组中小于平均值的数据依次移至数组的前部,大于等于平均值的数据依次移至x所指数组的后部,平均值作为函数值返回,在主函数中输出平均值和移动后的数据。 …