C语言数据结构总结:树

article/2025/8/19 5:24:21

  • 一,树的定义
  • 二,树的基本术语
  • 三,二叉树的定义
  • 四,二叉树的性质和存储结构
  • 五,关于二叉树的算法

一,树的定义

树是n(n>=0)个结点的有限集合。

若n=0,称为空树。
若n>0,则它满足如下两个条件;①有且仅有一个特定的称为根(root)的结点。②其余结点可分为m(m>=0)个互不相交的有限集合T1,T2….

其中每一个集合本身又是一棵树,并称为根的子树。

二,树的基本术语

在这里插入图片描述

①孩子与双亲:结点的子树的根称为该结点的孩子,该结点称为孩子的双亲。
②根结点:非空树中无前驱结点的结点。
③结点的度:结点拥有的子树的数目。
④树的度:树内各结点的度的最大值。
⑤树的深度:树中结点的最大层次。
⑥堂兄弟:双亲在同一层的结点。
⑦叶子:度等于0的结点。
⑧有序树:树中结点的各子树从左至右有次序。(最左边的为第一个孩子)
⑨无序树:树中结点的各子树无次序。
⑩森林:森林是m(m>=0)棵互不相交的树的集合。

(①把根结点删除,树就变成了森林。②一棵树可以看做是一个特殊的森林。③给森林的各子树加上一个双亲结点,森林就变成了树)。
树一定是森林,森林不一定是树。

三,二叉树的定义

二叉树是n(n>=0)个结点的有限集合,它或者是空集(n=0)或者是由一
个根结点及两棵互不相交的分别称作这个根的左子树和右子树的二叉树组成。

    特点:    ①每个结点最多有两个孩子(二叉树中不存在度大于2的结点)。②子树有左右之分,其次序不能颠倒。③二叉树可以是空集合,根可以有空的左子树或空的右子树。

二叉树不是树的特殊情况,它们是两个概念。
在这里插入图片描述

二叉树结点的子树要区分左子树和右子树,即使只有一棵子树也要进行区分,说明它是左子树,还是右子树。树当结点只有一个孩子时,就无须区分它是左还是右的次序。这是二叉树与树的最主要的差别。

(也就是说二叉树的每个结点位置或者说次序都是固定的,可以是空,但是不能说它没有位置,而树的结点位置是相对于别的结点来说的,没有别的结点时,它就无所谓左右了)。

四,二叉树的性质和存储结构

在这里插入图片描述
性质1:在二叉树的第i层上最多有 2^(i-1)个结点(i>=1)。

性质2:深度为k的二叉树最多有 2^k-1个结点(k>=1)。深度为k时至少有k个结点。

性质3:对任何一棵二叉树T,如果其叶子数为 m,度为2的结点数为 p,则m=p+1。 总边数为n-1或者为2p+m。

两种特殊形式的二叉树:
在这里插入图片描述

满二叉树:一棵深度为k且有2^k-1个结点的二叉树称为满二叉树。

      特点:①每一层上的结点数都是最结点数(每一层都满)。②对满二叉树的结点位置进行编号,从根结点开始,自上而下,自左而右,每一结点位置都有元素。

满二叉树在同样深度的二叉树中结点个数最多。

满二叉树在同样深度的二叉树中叶子结点个数最多。
在这里插入图片描述

完全二叉树:深度为k的具有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号为1~n的结点一一对应时,称之为完全二叉树。

   特点:①叶子只可能分布在层次最大的两层上。②对任一结点,如果其右子树的最大层次为i,则其左子树的最大层次为i或i+1。性质:①具有n个结点的完全二叉树的深度为【〖log〗_2^n】+1(【x】表示不大于x的最大整数)。   ②如果对一棵有n个结点的完全二叉树按层序编号,则对于任一结点i,有:1,如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲结点为【i/2】。2,如果2i>n,则结点为叶子结点,无左孩子;否则,其左孩子是结点2i。3,如果2i+1>n,则结点i无右孩子;否则,其右孩子时结点2i+1。

满二叉树一定是完全二叉树。

在满二叉树中,从最后一个结点开始,连续去掉任意个结点,即是一棵完全二叉树。在n个结点的二叉链表中,有n+1个空指针域。

五,关于二叉树的算法

一,遍历算法:

若规定先左后右,则只有前三种情况:

DLR——先序遍历

LDR——中序遍历

LRD——后序遍历

举个栗子:
Problem Description
已知二叉树的一个按先序遍历输入的字符序列,如abc,de,g,f, (其中,表示空结点)。请建立二叉树并按先序,中序和后序的方式遍历该二叉树。

Input
连续输入多组数据,每组数据输入一个长度小于50个字符的字符串。

Output
每组输入数据对应输出2行:
第1行输出先序遍历序列;
第2行输出中序遍历序列。
第3行输出后序遍历序列。

#include <stdio.h>
#include <stdlib.h>
struct node//二叉树的数据结构
{char ch;struct node *lchild,*rchild;
};
char s[100];
int key;
struct node *CreatTree()//建立二叉树
{struct node *T;if (s[key]==','){T=NULL;key++;}else{T=(struct node *)malloc(sizeof(struct node));T->ch=s[key++];T->lchild=CreatTree();T->rchild=CreatTree();}return T;
}
void PreOrderTraverse(struct node *T)//先序遍历二叉树
{if (T){printf("%c",T->ch);PreOrderTraverse(T->lchild);PreOrderTraverse(T->rchild);}
}
void InOrderTraverse(struct node *T)//中序遍历二叉树
{if (T){InOrderTraverse(T->lchild);printf("%c",T->ch);InOrderTraverse(T->rchild);}
}
void PostOrderTraverse(struct node *T)//后序遍历二叉树
{if (T){PostOrderTraverse(T->lchild);PostOrderTraverse(T->rchild);printf("%c",T->ch);}
}
int main()
{while (~scanf("%s",s)){key=0;struct node *T;T=CreatTree();PreOrderTraverse(T);printf("\n");InOrderTraverse(T);printf("\n");PostOrderTraverse(T);printf("\n");}return 0;
}

层序遍历:对于一棵二叉树,从根结点开始,按从上到下,从左到右的顺序访问每一个结点,每个结点仅仅访问一次。

举个栗子:

Problem Description
已知一个按先序输入的字符序列,如abd,eg,cf,(其中,表示空结点)。请建立二叉树并求二叉树的层次遍历序列。

Input
输入数据有多行,第一行是一个整数t (t<1000),代表有t行测试数据。每行是 一个长度小于50个字符的字符串。
Output
输出二叉树的层次遍历序列。
示例输入

2
abd,eg,cf,
xnl,i,u,

示例输出

abcdefg
xnuli

#include <stdio.h>
#include <stdlib.h>
struct node
{char data;struct node *lchild,*rchild;
};
int i;
char s[100];
struct node *creatTree()
{i++;struct node *p;if (s[i]==','){p=NULL;}else{p=(struct node *)malloc(sizeof(struct node));p->data=s[i];p->lchild=creatTree();p->rchild=creatTree();}return p;
}
void levelTraversal(struct node *p)//用队列实现
{struct node *q[100];q[0]=p;int head=0,tail=1;while (head<tail){if (q[head]!=NULL){printf("%c",q[head]->data);q[tail++]=q[head]->lchild;q[tail++]=q[head]->rchild;}head++;}
}
int main()
{int t;scanf("%d",&t);while (t--){struct node *p;scanf("%s",s);i=-1;p=creatTree();levelTraversal(p);printf("\n");}return 0;
}

二,其他算法

复制二叉树

举个栗子:
Problem Description
已知一个按先序输入的字符序列,如abd,eg,cf,(其中,表示,表示空结点),请复制这棵二叉树并输出。

#include <stdio.h>
#include <stdlib.h>
struct node
{char data;struct node *lchild,*rchild;
};
int i;
char s[100];
struct node *creatTree()
{i++;struct node *p;if (s[i]==','){p=NULL;}else{p=(struct node *)malloc(sizeof(struct node));p->data=s[i];p->lchild=creatTree();p->rchild=creatTree();}return p;
}
struct node *copy(struct node *p)//复制二叉树
{struct node *q;if (p==NULL){q=NULL;}else{q=(struct node *)malloc(sizeof(struct node));q->data=p->data;q->lchild=copy(p->lchild);q->rchild=copy(p->rchild);}return q;
}
void PreOrderTraverse(struct node *h)
{if (h){printf("%c",h->data);PreOrderTraverse(h->lchild);PreOrderTraverse(h->rchild);}
}
int main()
{scanf("%s",s);struct node *p,*q;i=-1;p=creatTree();q=copy(p);PreOrderTraverse(p);//输出原二叉树printf("\n");PreOrderTraverse(q);//输出复制后的二叉树printf("\n");return 0;
}

求二叉树的深度

举个栗子:
Problem Description
已知一个按先序输入的字符序列,如abd,eg,cf,(其中,表示,表示空结点),求这棵树的深度。

#include <stdio.h>
#include <stdlib.h>
struct node
{char data;struct node *lchild,*rchild;
};
int i;
char s[100];
struct node *creatTree()
{i++;struct node *p;if (s[i]==','){p=NULL;}else{p=(struct node *)malloc(sizeof(struct node));p->data=s[i];p->lchild=creatTree();p->rchild=creatTree();}return p;
}
int depth(struct node *h)//求二叉树的深度
{int n,m;if (h==NULL){return 0;}else{m=depth(h->lchild);n=depth(h->rchild);if (m>n){return (m+1);}else return (n+1);}
}
int main()
{scanf("%s",s);struct node *p;i=-1;p=creatTree();printf("%d\n",depth(p));return 0;
}

求二叉树的结点总数:

举个栗子:
Problem Description
已知一个按先序输入的字符序列,如abd,eg,cf,(其中,表示,表示空结点),求这棵树的结点总数。

#include <stdio.h>
#include <stdlib.h>
struct node
{char data;struct node *lchild,*rchild;
};
int i;
char s[100];
struct node *creatTree()
{i++;struct node *p;if (s[i]==','){p=NULL;}else{p=(struct node *)malloc(sizeof(struct node));p->data=s[i];p->lchild=creatTree();p->rchild=creatTree();}return p;
}
int score(struct node *h)//求结点总数
{if (h==NULL){return 0;}else{return score(h->lchild)+score(h->rchild)+1;}
}
int main()
{scanf("%s",s);struct node *p;i=-1;p=creatTree();printf("%d\n",score(p));return 0;
}

求叶子结点总数

举个栗子:
Problem Description
已知一个按先序输入的字符序列,如abd,eg,cf,(其中,表示,表示空结点),求这棵树的叶子结点总数。

#include <stdio.h>
#include <stdlib.h>
struct node
{char data;struct node *lchild,*rchild;
};
int i;
char s[100];
struct node *creatTree()
{i++;struct node *p;if (s[i]==','){p=NULL;}else{p=(struct node *)malloc(sizeof(struct node));p->data=s[i];p->lchild=creatTree();p->rchild=creatTree();}return p;
}
int deaf(struct node *h)//求叶子结点总数
{if (h==NULL){return 0;}if (h->lchild==NULL&&h->rchild==NULL){return 1;}else{return deaf(h->lchild)+deaf(h->rchild);}
}
int main()
{scanf("%s",s);struct node *p;i=-1;p=creatTree();printf("%d\n",deaf(p));return 0;
}

未完待续…


http://chatgpt.dhexx.cn/article/ev2EE2Qs.shtml

相关文章

【C++从入门到入土】第二十一篇:二叉搜索树之AVL树

AVL树 文章目录 AVL树一、AVL树1.特点2.操作旋转插入删除查找 一、AVL树 在计算机科学中&#xff0c;AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为1&#xff0c;所以它也被称为高度平衡树。增加和删除可能需要通过一次或多次树旋转来重新平…

数据结构--二叉搜索树

二叉搜索树 一丶概念以及特点二丶相关操作定义TreeMap类put()操作--插入节点get()操作--得到key对应的value值getOrDefault()操作containsKey()操作--检查key是否存在containsValue()操作--检查value是否存在remove()操作--删除操作思路&#xff08;1&#xff09;叶子结点&…

Java数据结构--树2

Java数据结构--树 一、平衡树1.1 2-3 查找树1.1.1 2-3查找树的定义1.1.2 查找1.1.3 插入1.1.3.1 向2-结点中插入新键1.1.3.2 向一棵只含有一个3-结点的树中插入新键1.1.3.3 向一个父结点为2-结点的3-结点中插入新键1.3.1.4 向一个父结点为3-结点的3-结点中插入新键1.3.1.5 分解…

数据结构之多路查找树

多路查找树 一、2-3树1.1 查找1.2 2-3树的插入实现1.3 2-3树的删除节点 二、2-3-4树三、总结 二叉排序树简单的实现在多数情况能够达到预期的查找效率&#xff0c;但是每个节点只能存储一个元素和只能有两个孩子&#xff0c;使得在大量数据下会造成二叉排序树的深度特别大&…

【数据结构 7】二叉查找树及其Java实现

【数据结构 1】顺序表及其Java实现 【数据结构 2】单向链表及其Java实现 【数据结构 3】双向链表及其Java实现 【数据结构 4】栈及其Java实现 【数据结构 5】队列及其Java实现 【数据结构 6】符号表及其Java实现&#xff08;使用链表实现&#xff09; 【数据结构 7】二叉查找树…

C++从入门到精通(第十篇) :二叉搜索树

二叉搜索树 一&#xff1a;二叉搜索树概念二&#xff1a; 二叉搜索树实现节点的定义二叉搜索树实现 三&#xff1a;二叉搜索树的应用四&#xff1a;二叉树有关面试题ps 很多小伙伴为了刷题发愁 今天为大家推荐一款刷题神奇哦&#xff1a;刷题面试神器牛客 各大互联网大厂面试真…

数据结构与算法之树(二)二叉查找树

数据结构与算法之树 数据结构与算法之树&#xff08;一&#xff09;二叉树概念及遍历方式&#xff08;图文并茂&#xff09; 数据结构与算法之树&#xff08;二&#xff09;二叉查找树 数据结构与算法之树&#xff08;三&#xff09;AVL树 数据结构与算法之树&#xff08;四…

【算法修炼】二叉搜索树

学习自&#xff1a;https://labuladong.gitee.io/algo/2/19/26/ 二叉搜索树 一、BST的中序遍历230、二叉搜索树中第k小的元素&#xff08;中等&#xff09;1038、从二叉搜索树到更大和树&#xff08;中等&#xff09; 二、判断BST的合法性※98、验证二叉搜索树&#xff08;中等…

数据结构(C语言)-树

树 一、树1、树的定义2、树的基本术语3、树结构和线性结构的比较 二、二叉树1、二叉树的定义2、二叉树的形态与树的形态3、二叉树的性质4 、二叉树的存储结构5、遍历二叉树6、二叉树的其他操作7、线索二叉树 三、树与二叉树的转换1、树转换成二叉树2、二叉树变树 四、哈夫曼树1…

【数据结构与算法】程序内功篇六--树

程序内功篇六--树 一、树1、树的含义2、树的特点(选看)3、树的逻辑结构 二、二叉树1、二叉树的含义2、二叉树性质3、二叉树-顺序存储4、二叉树-链式存储5、二叉树的遍历6、二叉树创建与遍历C程序的实现&#xff08;1&#xff09;二叉树的创建&#xff08;2&#xff09;前序遍历…

数据结构---与树相关的知识

与树有关的一系列知识: 树,二叉树,满二叉树,完全二叉树,文章还没完,我会后序补充的 一: 树(了解就行)1.1 概念1.2 一些与树相关的重要概念1.3 树的表示形式 二: 二叉树(非常重要,重点掌握)2.1 概念2.2 两种特殊的二叉树2.2.1 满二叉树2.2.2 完全二叉树 2.3 二叉树的性质2.4 二叉…

Java数据结构--树1

Java数据结构--树 一、二叉树入门1.1 树的基本定义1.2 树的相关术语1.3 二叉树的基本定义1.4 二叉查找树的创建1.4.1 二叉树的结点类1.4.2 二叉查找树API设计1.4.3 二叉查找树实现1.4.4 二叉查找树其他便捷方法1.4.4.1 查找二叉树中最小的键1.4.4.2 查找二叉树中最大的键 1.5 二…

树 一

文章目录 1.查找二分查找判定树 2. 树(Tree)2.1 树的术语2.2树的表示&#xff1a;儿子兄弟表示法 3. 二叉树&#xff08;Binary Tree&#xff09;3.1 特殊结构二叉树3.2 二叉树的性质3.3 二叉树的存储3.4二叉树的遍历 分层次组织管理上更有效地操作。 1.查找 静态查找&#xf…

树一:邂逅入门篇

一、树的概念 树是一种典型的非线性结构&#xff0c;是表达有层次特性的图结构的一种方法。 1.1 基本术语 术语描述空树当n0 时称为空树。根结点根结点是一个没有双亲结点的结点。一棵树最多一个。例如&#xff1a;A边结点之间的连线叶子结点没有孩子结点的结点。例如&#x…

树一:定义及存储

树的定义&#xff1a; 树是一种非线性的数据结构。树是由 n (n > 0) 个结点组成的有序集合。 如果 n 为0&#xff0c;称为空树&#xff1b;如果 n > 0, 则&#xff1a; 有一个结点称为根结点&#xff08;root&#xff09;&#xff0c;它有直接后继&#xff0c;但没有直接…

mysql 创建索引规则

1、表的主键、外键必须有索引&#xff1b; 2、数据量超过300的表应该有索引&#xff1b; 3、经常与其他表进行连接的表&#xff0c;在连接字段上应该建立索引&#xff1b; 4、经常出现在Where子句中的字段&#xff0c;特别是大表的字段&#xff0c;应该建立索引&#xff1b; 5、…

mysql分区表之三:MySQL分区建索引,唯一索引

介绍 mysql分区后每个分区成了独立的文件&#xff0c;虽然从逻辑上还是一张表其实已经分成了多张独立的表&#xff0c;从“information_schema.INNODB_SYS_TABLES”系统表可以看到每个分区都存在独立的TABLE_ID,由于Innodb数据和索引都是保存在".ibd"文件当中&#…

分享mysql创建索引的3种方法

大家应该都知道索引的建立对于MySQL数据库的高效运行是很重要的,索引可以大大提升MySQL的检索速度,下面这篇文章主要给大家介绍了关于mysql创建索引的3种方法,需要的朋友可以参考下 1、使用CREATE INDEX创建&#xff0c;语法如下&#xff1a; 1 CREATE INDEX indexName ON tab…

js 监听浏览器刷新还是关闭事件

// $(window).bind(beforeunload,function(){return 您输入的内容尚未保存&#xff0c;确定离开此页面吗&#xff1f;;}); // window.onbeforeunload function() { return "确定离开此页面吗&#xff1f;"; }; // function myFunction() {return "自定…

浏览器刷新和页面手动为什么不一样?

Fiddler(2):AutoResponse修改返回结果_mb5fed6ec4336ce的技术博客_51CTO博客Fiddler(2):AutoResponse修改返回结果&#xff0c;前言怎么修改接口的返回数据呢步骤1.抓包&#xff0c;找到要拦截的请求&#xff0c;然后在AutoResponder中AddRule&#xff1a;2.在RuleEditor中的第…