数据结构 ——树

此篇文章只是记录一下自己学习数据结构——树的笔记,不涉及代码;简单介绍一下树的各种概念,加深自己印象。

树:

概念:

是一种数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:
每个结点有零个或多个子结点;没有父结点的结点称为根结点;每一个非根结点有且只有一个父结点;除了根结点外,每个子结点可以分为多个不相交的子树; [1] (来自百度百科)

树的基本术语:

节点的度:节点所拥有子树的个数。

树的度:树中节点拥有最多子树的值(也即节点的度最大值)。

叶节点:度为0的节点。

分支节点: 度不为0 的节点。

孩子节点和双亲节点: 在树中,每个节点的后继都被成为该节点的孩子节点;孩子节点称该节点为双亲节点。

兄弟节点: 具有同一个双亲节点的结点。

树的深度:树中节点层次的最大值,称为树的高度。

有序树:树中的各节点的子树是按照从左到右有序排列,各子树的位置不能交换。

无序树:树中各节点排序无序。

森林:m(m>0)颗互不相交的树。

二叉树:每个节点最多有两课子树的树(节点的度只能为0,1,2)。

满二叉树:

二叉树的所有分支节点都有左子树和右子树,并且所有的叶子节点都在最后一层。

在这里插入图片描述

完全二叉树:

若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。

在这里插入图片描述

二叉树的五种形态

在这里插入图片描述

1.空树。(a)

2.只有根节点。(b)

3.只有左节点。©

4.只有右节点。(d)

5.完全二叉树。(e)

二叉树的性质

(1) 在非空二叉树中,第i层的节点数不超过 :2^i-1 (i> 1)。

(2)深度为h的二叉树,最多有2^h-1个节点(完全二叉树),最少有h个节点。

(3) 任意一个二叉树,如果其叶子节点数为N0,度为2的节点数为N2,那么
N0=N2+1。

(4) 具有n个节点的完全二叉树的深度为:
在这里插入图片描述

(5)有N个结点的完全二叉树各结点如果用顺序方式存储,则结点之间有如下关系:
若I为结点编号则 如果I>1,则其父结点的编号为I/2;
如果2I<=N,则其左儿子(即左子树的根结点)的编号为2I;若2I>N,则无左儿子;
如果2
I+1<=N,则其右儿子的结点编号为2I+1;若2I+1>N,则无右儿子。

(6)给定N个节点,能构成h(N)种不同的二叉树。
h(N)为卡特兰数的第N项。h(n)=C(2*n,n)/(n+1)。

(7)设有i个枝点,I为所有枝点的道路长度总和,J为叶的道路长度总和J=I+2i

平衡树和排序(查找)树

平衡二叉树,或是一棵空树,或符合以下特性:
【平衡特性1】:左子树的深度和右子树的深度相差不能超过1,可以是0(代表左右子树深度一样)、-1(代表左子树比右子树少一层)、1(代表左子树比右子树多一层)
【平衡特性2】它的左右子树也要是平衡二叉树
查找树,或是一棵空树,或满足符合以下特性:
【查找特性1】:若左子树不为空,左子树节点所有的值均要小于根节点;
【查找特性2】: 若右子树不为空,右子树节点所有的值均要大于根节点;
【查找特性3】它的左右子树也要是查找树

任何树中,分支数比节点数少1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Keil MDK中使用可以通过定义节点结构体和使用指针来实现。下面是一个简单的示例代码: ```c #include <stdio.h> #include <stdlib.h> // 定义节点结构体 typedef struct node { int data; struct node *left; struct node *right; } TreeNode; // 创建节点 TreeNode* create_node(int data) { TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode)); node->data = data; node->left = NULL; node->right = NULL; return node; } // 插入节点 TreeNode* insert_node(TreeNode* root, int data) { if (root == NULL) { return create_node(data); } if (data < root->data) { root->left = insert_node(root->left, data); } else { root->right = insert_node(root->right, data); } return root; } // 计算的深度 int tree_depth(TreeNode* root) { if (root == NULL) { return 0; } int left_depth = tree_depth(root->left); int right_depth = tree_depth(root->right); return (left_depth > right_depth ? left_depth : right_depth) + 1; } int main() { // 创建根节点 TreeNode* root = create_node(5); // 插入节点 root = insert_node(root, 3); root = insert_node(root, 7); root = insert_node(root, 1); root = insert_node(root, 4); root = insert_node(root, 6); root = insert_node(root, 8); // 计算的深度并输出 int depth = tree_depth(root); printf("Tree Depth: %d\n", depth); return 0; } ``` 在这个示例代码中,我们首先定义了一个节点结构体,包含了节点据和左右子节点指针。然后我们定义了创建节点和插入节点的函,使用递归的方式实现。最后我们定义了计算深度的函,并在main函中使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值