数据结构--第六天

news/2024/9/22 14:56:18/

--树

        -树的基本概念

树结构通常用来储存逻辑关系为“一对多”的数据,例如:

上图的这些元素具有的就是 "一对多" 的逻辑关系,例如元素A同时和B、C、D有关系,元素D同时和A、H、I、J有关系等。 观察这些元素之间的逻辑关系会发现,它们整体上像一棵倒着的树,这也是将存储这些元素的结构起名为“树”的原因

        tips:树型结构可以保证数据的插入、删除、修改的速度

        -树的定义

          1. 树是由节点构成

          2. 树中除根节点,每一个节点都只有一个父节点,但是可以有多个子节点

          3. 根节点没有父节点

        -树中的专业术语

          节点:树结构存储的各个元素称为节点,例如:父节点,子节点,叶子节点

          节点的度:一个节点拥有子树的个数,就称为该节点的度

          叶子节点:没有子节点的节点,称为叶子节点

          边:一个节点到另一个节点的距离

          树的深度:树中结点的层数,根节点默认为第一层

          有序树: 如果一棵树中各个节点左子树和右子树的位置不能交换,那么这棵树就称为有序树

          无序树: 如果一棵树中各个节点左子树和右子树的位置可以交换,那么这棵树就称为无序树

          空树: 指没有任何节点的树,连根节点都没有

        -树的分类

           一般树:任意节点的子节点的个数不受限制,则称为一般树

           二叉树任意一个节点的子节点个数最多是2个

           森林:由多个树共同组成一片森林

        -二叉树的特性

           1.二叉树和链表一样,也是动态数据结构

            其结构体格式:

                struct Node{

                    datatype_t data;

                    struct Node* left;

                    struct Node* right;

                }

           2.二叉树具有唯一的根节点

           3.二叉树具有天然的递归结构(每个节点的左、右子树也是二叉树)

          满二叉树

                1>叶子节点出现在二叉树的最底层,除叶子节点之外的其他节点都有俩个子节点

                2>一个层数为k的满二叉树的总节点数为:2^k-1

                3>第i层上节点数为:2^(i-1) 

                4>一个层数为k的满二叉树的叶子节点个数(也就是最后一层)为:2^(k-1)

           完全二叉树

                概念:按照树的结构从上到下,从左到右依次将元素排列成树的形状

                性质:

                  1>根节点没有父节点

                  2>除根节点之外的任意节点(i)的父节点的索引为:(i-1)/2

                  3>任意节点的左子节点的的索引为:2*i+1

                  4>任意节点的右子节点的的索引为:2*i+2

        -二叉树的遍历

           二叉树的遍历是指从根结点触发,按照某种次序访问二叉树中所有节点,使得每个节点被访问且仅被访问一次

           四种常用遍历思想为:

                前序遍历:根节点-->左子树-->右子树

                中序遍历:左子树-->根节点-->右子树

                后序遍历:左子树-->右子树-->根节点

                层次遍历:只需按层次遍历即可

        -树示例代码

           main.c
#include "tree.h"void menu(){printf("--------------------------------\n");printf("1.create tree\n");printf("2.preorder tree\n");printf("3.midorder tree\n");printf("4.suffixorder tree\n");printf("show complete binary tree array\n");printf("0.exit\n");printf("--------------------------------\n");
}int main(){int select;node_t* root=NULL;do{menu();printf("请选择:");scanf("%d",&select);switch(select){case 1:while(getchar()!='\n');create_tree2(&root);break;case 2:printf("-------------------pre traversal----------------------\n");pre_traversal(root);putchar('\n');break;case 3:printf("-------------------middle traversal----------------------\n");middle_traversal(root);putchar('\n');break;case 4:printf("-------------------suf traversal----------------------\n");suf_traversal(root);putchar('\n');break;case 5:printf("-------------------level traversal----------------------\n");level_traversal(root);putchar('\n');break;case 0:printf("退出成功!\n");free(root);root=NULL;exit(EXIT_FAILURE);}}while(1);return 0;
}
        tree.c
#include "tree.h"//创建树的方法
void create_tree2(node_t** p_root){//创建一个节点char c;scanf("%c",&c);if(c=='#'){return; }node_t* p_node=(node_t*)malloc(sizeof(node_t));if(NULL==p_node){printf("malloc failure\n");return;}p_node->data=c;create_tree2(&(p_node->left));create_tree2(&(p_node->right));*p_root=p_node;
}node_t* create_tree(){//创造节点printf("input character:");char c;scanf("%c",&c);if(c=='#'){return NULL;}node_t* p_node=(node_t*)malloc(sizeof(node_t));if(NULL==p_node){printf("malloc failure.\n");return NULL;}p_node->data=c;//创建左子树p_node->left=create_tree();//创建右子树p_node->right=create_tree();return p_node;
}
//前序遍历
void pre_traversal(node_t* root){//递归终止条件if(NULL==root){return;}//递归操作printf("%-3c",root->data);pre_traversal(root->left);pre_traversal(root->right);
}
void middle_traversal(node_t* root){                          //递归终止条件if(NULL==root){                                    return;                                    }//递归操作middle_traversal(root->left);printf("%-3c",root->data);middle_traversal(root->right);                        
}
void suf_traversal(node_t* root){//递归终止条件if(NULL==root){return;}//递归操作suf_traversal(root->left);suf_traversal(root->right);printf("%-3c",root->data);
}void level_traversal(node_t* root){if(NULL==root){return;}//创建队列linkednode_t* queue=NULL;linkedlist_init(&queue);//1.将头节点入队linkedlist_insert_tail(queue,root);while(!linkedlist_is_empty(queue)){//2.出队node_t* node=linkedlist_remove_head(queue);printf("%-3c",node->data);//3.分别判断左右子树是否为空if(node->left!=NULL){linkedlist_insert_tail(queue,node->left);}if(node->right!=NULL){linkedlist_insert_tail(queue,node->right);}}
}
        tree.h
#ifndef _HEAD_COMPLETE_BT_H__
#define _HEAD_COMPLETE_BT_H__#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>
#include "linkedlist.h"extern void create_tree2(node_t**);
extern void pre_traversal(node_t*);
extern void middle_traversal(node_t*);
extern void suf_traversal(node_t*);
extern void level_traversal(node_t*);
extern node_t* create_tree();#endif
        linkedlist.c
#include "linkedlist.h"void linkedlist_init(linkednode_t** p_head){                                         linkednode_t* p_node = (linkednode_t*)malloc(sizeof(linkednode_t));        if(p_node==NULL){                                        printf("malloc failure:%s\n",strerror(errno));   return;                                    }                                                        memset(p_node,0,sizeof(linkednode_t));                                                              p_node->next = NULL; *p_head = p_node;	
}// 添加的方法
bool linkedlist_insert_tail(linkednode_t* p_head,node_t* data){//将data添加到链表的尾部// 1、封装成节点linkednode_t* p_node = (linkednode_t*)malloc(sizeof(linkednode_t));if(p_node==NULL){printf("malloc failure:%s\n",strerror(errno));return false;}memset(p_node,0,sizeof(linkednode_t));p_node->data = data;p_node->next = NULL;// 1、找到链表的尾部linkednode_t* tail = p_head;while(tail->next!=NULL){tail= tail->next;}// 2、进行挂接tail->next=p_node;return true;
}bool linkedlist_is_empty(linkednode_t* head){return head == NULL || head->next==NULL;
}node_t* linkedlist_remove_head(linkednode_t* head){if(linkedlist_is_empty(head)){return NULL;}else{linkednode_t* delnode = head->next;head->next = head->next->next;return delnode->data;	}
}
        输出结果


http://www.ppmy.cn/news/1508939.html

相关文章

Python管理myql、搭建frp服务上线mysql数据库、Python生成可执行文件及python模块发布web服务

Day 21 复习 [rootpython ~]# vim test03.py a3 b4 print(ab) print(a**2b**2) [rootpython ~]# python3 test03.py 7 25 # 逐行调试 [rootpython ~]# python3 -m pdb test03.py > /root/test03.py(1)<module>() -> a3 (Pdb) n > /root/test03.p…

香橙派下安装neo4j

在香橙派(Orange Pi)上安装Neo4j图数据库可以通过以下步骤完成。假设你使用的是基于Debian的Linux发行版(如Armbian),以下是详细的安装步骤: 1. 更新系统 首先,确保你的系统是最新的。打开终端并运行以下命令: sudo apt update sudo apt upgrade -y 2. 安装Java N…

YOLT论文精读

引言 很早之前&#xff0c;在本校老师的带领下接触到了目标检测领域。在卫星遥感图像方面有一篇经典的论文《You Only Look Twice: Rapid Multi-Scale Object Detection In Satellite Imagery》。科研小白一开始反复看了几遍也没弄懂&#xff0c;决定写博客来加深自己的理解。…

花式表演无人机技术详解

花式表演无人机作为现代科技与艺术融合的典范&#xff0c;以其独特的飞行姿态、绚烂的灯光效果及精准的控制能力&#xff0c;在各类庆典、体育赛事、音乐会等合中展现出非凡的魅力。本文将从以下几个方面对花式表演无人机技术进行详细解析。 1. 三维建模与编程 在花式表演无人…

在Debian上安装freeswitch

在Debian上安装freeswitch 说明&#xff1a; 首次发表日期&#xff1a;2024-08-12参考文档&#xff1a; https://medium.com/jogikrunal9477/ultimate-guide-to-installing-freeswitch-on-ubuntu-22-04-lts-3745ef6a6bd6https://developer.signalwire.com/freeswitch/FreeSWI…

vue2+OpenLayers 天地图上画图层(3)把当前的图层放上去

点击画笔按钮 开始框画 取当前的裁剪图层为后面的图层 恢复画笔 这里提前引入了Draw import Draw, { createRegularPolygon, createBox } from "ol/interaction/Draw";代码如下 <template><div class"container"><div id"vue-openlay…

PDF转markdown工具:magic-pdf

1. magic-pdf 环境安装 conda create -n MinerU python3.10 conda activate MinerU pip install boto3>1.28.43 -i https://pypi.tuna.tsinghua.edu.cn/simple/ pip install magic-pdf[full]0.7.0b1 --extra-index-url https://wheels.myhloli.com -i https://pypi.tuna.t…

[ACP云计算]易混淆知识点(考题总结)

ECS 1、ECS所在的地域叫做Region&#xff0c;可用区叫做Zone。每个地域完全独立&#xff0c;每个可用区完全隔离。 同地域下不同可用区之间的距离大概在数十公里。 2、伸缩组 ECS实例和伸缩组必须在同一个地域&#xff0c;但是对可用区没有要求。 ECS同一时刻只能加入到一…