C语言二叉树

合集下载

判断一棵树是否为满二叉树的算法c语言

判断一棵树是否为满二叉树的算法c语言

判断一棵树是否为满二叉树的算法c语言判断一棵树是否为满二叉树的算法(C语言)满二叉树是一种特殊的二叉树,每个节点要么没有子节点,要么有两个子节点。

判断一棵树是否为满二叉树的算法可以通过以下步骤实现:1. 定义二叉树的数据结构在C语言中,可以使用结构体定义二叉树的节点。

每个节点包含一个数据域和两个指针域,分别指向左子节点和右子节点。

```cstruct TreeNode {int data;struct TreeNode* left;struct TreeNode* right;};```2. 实现判断函数编写一个递归函数,用于判断给定二叉树是否为满二叉树。

函数的输入参数为根节点指针,返回值为布尔类型。

```cint isFullBinaryTree(struct TreeNode* root) {// 如果根节点为空,则返回真if (root == NULL) {return 1;}// 如果只有一个子节点或没有子节点,则返回假if ((root->left == NULL && root->right != NULL) ||(root->left != NULL && root->right == NULL)) {return 0;}// 递归判断左子树和右子树return isFullBinaryTree(root->left) && isFullBinaryTree(root->right);}```3. 测试样例可以编写一些测试样例来验证判断函数的正确性。

例如,下面是一个满二叉树和一个非满二叉树的示例:```cint main() {// 满二叉树struct TreeNode* root1 = (struct TreeNode*)malloc(sizeof(struct TreeNode));root1->data = 1;root1->left = (struct TreeNode*)malloc(sizeof(struct TreeNode));root1->left->data = 2;root1->left->left = (struct TreeNode*)malloc(sizeof(struct TreeNode));root1->left->left->data = 4;root1->left->left->left = NULL;root1->left->left->right = NULL;root1->left->right = (struct TreeNode*)malloc(sizeof(struct TreeNode));root1->left->right->data = 5;root1->left->right->left = NULL;root1->left->right->right = NULL;root1->right = (struct TreeNode*)malloc(sizeof(struct TreeNode));root1->right->data = 3;root1->right->left = (struct TreeNode*)malloc(sizeof(struct TreeNode));root1->right->left->data = 6;root1->right->left->left = NULL;root1->right->left->right = NULL;root1->right->right = (struct TreeNode*)malloc(sizeof(struct TreeNode));root1->right->right->data = 7;root1->right->right->left = NULL;root1->right->right->right = NULL;// 非满二叉树struct TreeNode* root2 = (struct TreeNode*)malloc(sizeof(struct TreeNode));root2->data = 1;root2->left = (struct TreeNode*)malloc(sizeof(struct TreeNode));root2->left->data = 2;root2->left->left = (struct TreeNode*)malloc(sizeof(struct TreeNode));root2->left->left->data = 4;root2->left->left->left = NULL;root2->left->left->right = NULL;root2->right = (struct TreeNode*)malloc(sizeof(struct TreeNode));root2->right->data = 3;root2->right->left = NULL;root2->right->right = (struct TreeNode*)malloc(sizeof(struct TreeNode));root2->right->right->data = 7;root2->right->right->left = NULL;root2->right->right->right = NULL;// 判断是否为满二叉树if (isFullBinaryTree(root1)) {printf("root1是满二叉树\n");} else {printf("root1不是满二叉树\n");}if (isFullBinaryTree(root2)) {printf("root2是满二叉树\n");} else {printf("root2不是满二叉树\n");}return 0;}```运行上述代码,输出结果为:```root1是满二叉树root2不是满二叉树```根据以上算法和示例,我们可以判断一棵树是否为满二叉树。

数据结构c语言课设-二叉树排序

数据结构c语言课设-二叉树排序

题目:二叉排序树的实现1 内容和要求1)编程实现二叉排序树,包括生成、插入,删除;2)对二叉排序树进展先根、中根、和后根非递归遍历;3)每次对树的修改操作和遍历操作的显示结果都需要在屏幕上用树的形状表示出来。

4)分别用二叉排序树和数组去存储一个班(50 人以上)的成员信息(至少包括学号、姓名、成绩3 项),比照查找效率,并说明在什么情况下二叉排序树效率高,为什么?2 解决方案和关键代码2.1 解决方案:先实现二叉排序树的生成、插入、删除,编写DisplayBST函数把遍历结果用树的形状表示出来。

前中后根遍历需要用到栈的数据构造,分模块编写栈与遍历代码。

要求比照二叉排序树和数组的查找效率,首先建立一个数组存储一个班的成员信息,分别用二叉树和数组查找,利用clock〔〕函数记录查找时间来比照查找效率。

2.2关键代码树的根本构造定义及根本函数typedef struct{KeyType key;} ElemType;typedef struct BiTNode//定义链表{ElemType data;struct BiTNode *lchild, *rchild;}BiTNode, *BiTree, *SElemType;//销毁树int DestroyBiTree(BiTree &T){if (T != NULL)free(T);return 0;}//清空树int ClearBiTree(BiTree &T){if (T != NULL){T->lchild = NULL;T->rchild = NULL;T = NULL;}return 0;}//查找关键字,指针p返回int SearchBST(BiTree T, KeyType key, BiTree f, BiTree &p) {if (!T){p = f;return FALSE;}else if EQ(key, T->data.key){p = T;return TRUE;}else if LT(key, T->data.key)return SearchBST(T->lchild, key, T, p);elsereturn SearchBST(T->rchild, key, T, p);}二叉树的生成、插入,删除生成void CreateBST(BiTree &BT, BiTree p){int i;ElemType k;printf("请输入元素值以创立排序二叉树:\n");scanf_s("%d", &k.key);for (i = 0; k.key != NULL; i++){//判断是否重复if (!SearchBST(BT, k.key, NULL, p)){InsertBST(BT, k);scanf_s("%d", &k.key);}else{printf("输入数据重复!\n");return;}}}插入int InsertBST(BiTree &T, ElemType e){BiTree s, p;if (!SearchBST(T, e.key, NULL, p)){s = (BiTree)malloc(sizeof(BiTNode));s->data = e;s->lchild = s->rchild = NULL;if (!p)T = s;else if LT(e.key, p->data.key)p->lchild = s;elsep->rchild = s;return TRUE;}else return FALSE;}删除//某个节点元素的删除int DeleteEle(BiTree &p){BiTree q, s;if (!p->rchild) //右子树为空{q = p;p = p->lchild;free(q);}else if (!p->lchild) //左子树为空{q = p;p = p->rchild;free(q);}else{q = p;s = p->lchild;while (s->rchild){q = s;s = s->rchild;}p->data = s->data;if (q != p)q->rchild = s->lchild;elseq->lchild = s->lchild;delete s;}return TRUE;}//整棵树的删除int DeleteBST(BiTree &T, KeyType key) //实现二叉排序树的删除操作{if (!T){return FALSE;}else{if (EQ(key, T->data.key)) //是否相等return DeleteEle(T);else if (LT(key, T->data.key)) //是否小于return DeleteBST(T->lchild, key);elsereturn DeleteBST(T->rchild, key);}return 0;}二叉树的前中后根遍历栈的定义typedef struct{SElemType *base;SElemType *top;int stacksize;}SqStack;int InitStack(SqStack &S) //构造空栈{S.base = (SElemType*)malloc(STACK_INIT_SIZE *sizeof(SElemType));if (!S.base) exit(OVERFLOW);S.top = S.base;S.stacksize = STACK_INIT_SIZE;return OK;}//InitStackint Push(SqStack &S, SElemType e) //插入元素e为新栈顶{if (S.top - S.base >= S.stacksize){S.base = (SElemType*)realloc(S.base, (S.stacksize + STACKINCREMENT)*sizeof(SElemType));if (!S.base) exit(OVERFLOW);S.top = S.base + S.stacksize;S.stacksize += STACKINCREMENT;}*S.top++ = e;return OK;}//Pushint Pop(SqStack &S, SElemType &e) //删除栈顶,应用e返回其值{if (S.top == S.base) return ERROR;e = *--S.top;return OK;}//Popint StackEmpty(SqStack S) //判断是否为空栈{if (S.base == S.top) return TRUE;return FALSE;}先根遍历int PreOrderTraverse(BiTree T, int(*Visit)(ElemType e)) {SqStack S;BiTree p;InitStack(S);p = T;while (p || !StackEmpty(S)){if (p){Push(S, p);if (!Visit(p->data)) return ERROR;p = p->lchild;}else{Pop(S, p);p = p->rchild;}}return OK;}中根遍历int InOrderTraverse(BiTree T, int(*Visit)(ElemType e)) {SqStack S;BiTree p;InitStack(S);p = T;while (p || !StackEmpty(S)){if (p){Push(S, p);p = p->lchild;}else{Pop(S, p);if (!Visit(p->data)) return ERROR;p = p->rchild;}}return OK;}后根遍历int PostOrderTraverse(BiTree T, int(*Visit)(ElemType e)) {SqStack S, SS;BiTree p;InitStack(S);InitStack(SS);p = T;while (p || !StackEmpty(S)){if (p){Push(S, p);Push(SS, p);p = p->rchild;}else{if (!StackEmpty(S)){Pop(S, p);p = p->lchild;}}}while (!StackEmpty(SS)){Pop(SS, p);if (!Visit(p->data)) return ERROR;}return OK;}利用数组存储一个班学生信息ElemType a[] = { 51, "陈继真", 88,82, "黄景元", 89,53, "贾成", 88,44, "呼颜", 90,25, "鲁修德", 88,56, "须成", 88,47, "孙祥", 87, 38, "柏有患", 89, 9, " 革高", 89, 10, "考鬲", 87, 31, "李燧", 86, 12, "夏祥", 89, 53, "余惠", 84, 4, "鲁芝", 90, 75, "黄丙庆", 88, 16, "李应", 89, 87, "杨志", 86, 18, "李逵", 89, 9, "阮小五", 85, 20, "史进", 88, 21, "秦明", 88, 82, "杨雄", 89, 23, "刘唐", 85, 64, "武松", 88, 25, "李俊", 88, 86, "卢俊义", 88, 27, "华荣", 87, 28, "杨胜", 88, 29, "林冲", 89, 70, "李跃", 85, 31, "蓝虎", 90, 32, "宋禄", 84, 73, "鲁智深", 89, 34, "关斌", 90, 55, "龚成", 87, 36, "黄乌", 87, 57, "孔道灵", 87, 38, "张焕", 84, 59, "李信", 88, 30, "徐山", 83, 41, "秦祥", 85, 42, "葛公", 85, 23, "武衍公", 87, 94, "范斌", 83, 45, "黄乌", 60, 67, "叶景昌", 99, 7, "焦龙", 89, 78, "星姚烨", 85, 49, "孙吉", 90, 60, "陈梦庚", 95,};数组查询函数void ArraySearch(ElemType a[], int key, int length){int i;for (i = 0; i <= length; i++){if (key == a[i].key){cout << "学号:" << a[i].key << " 姓名:" << a[i].name << " 成绩:" << a[i].grade << endl;break;}}}二叉树查询函数上文二叉树根本函数中的SearchBST()即为二叉树查询函数。

c语言哈夫曼树的构造及编码

c语言哈夫曼树的构造及编码

c语言哈夫曼树的构造及编码一、哈夫曼树概述哈夫曼树是一种特殊的二叉树,它的构建基于贪心算法。

它的主要应用是在数据压缩和编码中,可以将频率高的字符用较短的编码表示,从而减小数据存储和传输时所需的空间和时间。

二、哈夫曼树的构造1. 哈夫曼树的定义哈夫曼树是一棵带权路径长度最短的二叉树。

带权路径长度是指所有叶子节点到根节点之间路径长度与其权值乘积之和。

2. 构造步骤(1) 将待编码字符按照出现频率从小到大排序。

(2) 取出两个权值最小的节点作为左右子节点,构建一棵新的二叉树。

(3) 将新构建的二叉树加入到原来排序后队列中。

(4) 重复上述步骤,直到队列只剩下一个节点,该节点即为哈夫曼树的根节点。

3. C语言代码实现以下代码实现了一个简单版哈夫曼树构造函数:```ctypedef struct TreeNode {int weight; // 权重值struct TreeNode *leftChild; // 左子节点指针struct TreeNode *rightChild; // 右子节点指针} TreeNode;// 构造哈夫曼树函数TreeNode* createHuffmanTree(int* weights, int n) {// 根据权值数组构建节点队列,每个节点都是一棵单独的二叉树TreeNode** nodes = (TreeNode**)malloc(sizeof(TreeNode*) * n);for (int i = 0; i < n; i++) {nodes[i] = (TreeNode*)malloc(sizeof(TreeNode));nodes[i]->weight = weights[i];nodes[i]->leftChild = NULL;nodes[i]->rightChild = NULL;}// 构建哈夫曼树while (n > 1) {int minIndex1 = -1, minIndex2 = -1;for (int i = 0; i < n; i++) {if (nodes[i] != NULL) {if (minIndex1 == -1 || nodes[i]->weight < nodes[minIndex1]->weight) {minIndex2 = minIndex1;minIndex1 = i;} else if (minIndex2 == -1 || nodes[i]->weight < nodes[minIndex2]->weight) {minIndex2 = i;}}}TreeNode* newNode =(TreeNode*)malloc(sizeof(TreeNode));newNode->weight = nodes[minIndex1]->weight + nodes[minIndex2]->weight;newNode->leftChild = nodes[minIndex1];newNode->rightChild = nodes[minIndex2];// 将新构建的二叉树加入到原来排序后队列中nodes[minIndex1] = newNode;nodes[minIndex2] = NULL;n--;}return nodes[minIndex1];}```三、哈夫曼编码1. 哈夫曼编码的定义哈夫曼编码是一种前缀编码方式,它将每个字符的编码表示为二进制串。

二叉排序树c语言代码实现

二叉排序树c语言代码实现
printf ("是否继续输入?\n 1.是 2.否(其他键 退出)\n");
if ((*n) != NULL) {
free (*n);
*n = NULL;
}
}
/* 查找结点 */
PNODE find_node (PNODE n, int value) {
in_order_traversal ( n->right);
}
}
int main() {
char buf[50],a[1000];
int i,n,option,s[80],p;
PNODE tree = NULL;/*树的第一个结点*/
PNODE node = NULL;
{
r = (PNODE)malloc(sizeof(NODE));
if(!r)
{
printf("内存分配失败!");
exit(0);
zjm3:fgets (buf, sizeof(buf), stdin);
sscanf (buf, "%i", &option);
printf ("\n\n");
if(option<0) {
printf ("输入错误,请重新输入该元素\n",n);
goto zjm3;}
if(find_node (tree, option))
{
(*n)->value = value;
(*n)->left = NULL;
(*n)->right = NULL;
}
}

数据结构-C语言-树和二叉树

数据结构-C语言-树和二叉树

练习
一棵完全二叉树有5000个结点,可以计算出其
叶结点的个数是( 2500)。
二叉树的性质和存储结构
性质4: 具有n个结点的完全二叉树的深度必为[log2n]+1
k-1层 k层
2k−1−1<n≤2k−1 或 2k−1≤n<2k n k−1≤log2n<k,因为k是整数
所以k = log2n + 1
遍历二叉树和线索二叉树
遍历定义
指按某条搜索路线遍访每个结点且不重复(又称周游)。
遍历用途
它是树结构插入、删除、修改、查找和排序运算的前提, 是二叉树一切运算的基础和核心。
遍历规则 D
先左后右
L
R
DLR LDR LRD DRL RDL RLD
遍历规则
A BC DE
先序遍历:A B D E C 中序遍历:D B E A C 后序遍历:D E B C A
练习 具有3个结点的二叉树可能有几种不同形态?普通树呢?
5种/2种
目 录 导 航 Contents
5.1 树和二叉树的定义 5.2 案例引入 5.3 树和二叉树的抽象数据类型定义 5.4 二叉树的性质和存储结构 5.5 遍历二叉树和线索二叉树 5.6 树和森林 5.7 哈夫曼树及其应用 5.8 案例分析与实现
(a + b *(c-d)-e/f)的二叉树
目 录 导 航 Contents
5.1 树和二叉树的定义 5.2 案例引入 5.3 树和二叉树的抽象数据类型定义 5.4 二叉树的性质和存储结构 5.5 遍历二叉树和线索二叉树 5.6 树和森林 5.7 哈夫曼树及其应用 5.8 案例分析与实现
二叉树的抽象数据类型定义
特殊形态的二叉树
只有最后一层叶子不满,且全部集中在左边

数据结构(C语言版CHAP6(1)

数据结构(C语言版CHAP6(1)

G
说明 1)二叉树中每个结点最多有两颗子树;二叉树每个结点度小于等于2; 2)左、右子树不能颠例——有序树; 3)二叉树是递归结构,在二叉树的定义中又用到了二叉树的概念;
结束
第 16 页
6.2 二 叉 树
A B D G (a) E C F F C
A B D G (b) E
(a)、(b)是不同的二叉树, (a)的左子树有四个结点, (b)的左子树有两个结点,
结束
第 17 页
6.2 二 叉 树
2. 二叉树的基本形态
φ
结束
第 18 页
6.2 二 叉 树
3.应用举例 例1 可以用二叉树表示表达式
+ a * /
e
f
b
c
d
a+b*(c-d)-e/f
结束
ห้องสมุดไป่ตู้
第 19 页
6.2 二 叉 树
例2 双人比赛的所有可能的结局
开始

开局连赢两局 或五局三胜


甲 甲 乙

对于线性结构由于每个结点只有一个直接后继,遍历是很容易的事 二叉树是非线性结构,每个结点可能有两个后继,如 何访问二叉树的每个结点,而且每个结点仅被访问一次?
结束
第 32 页
6.3
一 二叉树的遍历方法
二叉树的遍历
二叉树由根、左子树、右子树三部分组成 二叉树的遍历可以分解为:访问根,遍历左子树和遍历右子树 令:L:遍历左子树 D:访问根结点 R:遍历右子树 有六种遍历方法: DLR,LDR,LRD,
3)树的结点,可以有零个或多个后继; 4)除根外的其他结点,都存在唯一条从根到该结点的路径; 5)树是一种分枝结构

二叉树 c语言

二叉树 c语言

二叉树 c语言在计算机科学领域中,树型数据结构是一种非常重要的数据结构,在实际开发中也得到了广泛的应用。

其中,二叉树又是一种非常常见的树型结构。

二叉树在很多情况下都能够提供更好的算法效率,同时也易于理解和实现,因此我们可以通过通过学习和掌握二叉树的特点以及优点,来更好的应用到实际开发中。

一、二叉树的定义二叉树是一种树型结构,树型结构是由节点构成的。

二叉树与一般的树型结构不同,它的每个节点最多只有两个子节点,分别称为左子树和右子树。

它们可以为空或者不为空,其子节点的数量时不固定且没有任何限制的。

二叉树的定义如下:(1)空树是树的一种特殊的状态。

我们可以把它称为二叉树;(2)若不是空树,那么它就是由一个称为根节点(root)的元素和左右两棵分别称为左子树(left subtree)和右子树(right subtree)的二叉树组成。

二、二叉树的特性(1)每个节点最多只有两个子节点,分别称为左子节点和右子节点;(2)左子树和右子树是二叉树;(3)二叉树没有重复的节点。

三、二叉树的应用二叉树是一种非常实用的数据结构,因为它可以模拟很多实际生活中的情况。

例如,我们可以利用二叉树来对某些数据进行分类和排序。

在二叉树的基础上,我们还可以构造二叉堆、哈夫曼树等更高级的数据结构。

除此之外,二叉树还可以应用到程序设计中。

例如,我们可以构造一个二叉树来表示某个程序的控制流,这个程序在执行时可以沿着二叉树的各个节点进行分支和选择,实现不同的功能。

此外,我们还可以利用二叉树来加快某些算法的执行效率,比如二分查找算法等。

四、二叉树的遍历方式对于二叉树的遍历,有三种基本方式,即前序遍历、中序遍历、后序遍历。

它们的遍历顺序不同,因此也得到了不同的称呼。

下面我们来简要介绍一下这三种遍历方式的特点和应用。

(1)前序遍历前序遍历是指首先访问树的根节点,然后按照从左到右的顺序依次遍历左子树和右子树。

前序遍历的应用非常广泛,可以用于生成表达式树、构造二叉树等等。

数据结构C语言版_线索二叉树

数据结构C语言版_线索二叉树
// 中序遍历二叉线索树T(头结点)的非递归算法。
int InOrderTraverse_Thr(BiThrTree T,int(*Visit)(TElemType))
{
BiThrTree p;
p=T->lchild; // p指向根结点
while(p!=T)
{ // 空树或遍历结束时,p==T
// 空格(字符型)表示空结点
int CreateBiThrTree(BiThrTree *T)
{
TElemType h;
scanf("%c",&h);
if(h==Nil)
*T=NULL;
else
{
*T=(BiThrTree)malloc(sizeof(BiThrNode));
if(!p->lchild) // 没有左孩子
{ Biblioteka p->LTag=Thread; // 前驱线索
p->lchild=pre; // 左孩子指针指向前驱
}
if(!pre->rchild) // 前驱没有右孩子
{
pre->RTag=Thread; // 后继线索
"b为左子树的二叉树)\n");
CreateBiThrTree(&T); // 按先序产生二叉树
InOrderThreading(&H,T); // 中序遍历,并中序线索化二叉树
printf("中序遍历(输出)二叉线索树:\n");
InOrderTraverse_Thr(H,vi); // 中序遍历(输出)二叉线索树
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据结构总结
32
• 基本形态
Φ
A
A
A
A
B 空二叉树 只有根结点 的二叉树 右子树为空
B
B
C 左、右子树 均非空
左子树为空
二叉树性质
• 性质1: 在二叉树的第i层上至多有2 i −1 个结点(i ≥ 1)
证明:用归纳法证明之 2i−1 = 20 = 1 i=1时,只有一个根结点, 是对的 j −1 假设对所有j(1≤j<i)命题成立,即第j层上至多有 2 j(1≤j<i) j 个结点 i−2 那么,第i-1层至多有2 个结点 又二叉树每个结点的度至多为2 ∴ 第i层上最大结点数是第i-1层的2倍,即 2 ⋅ 2i −2 = 2i −1 故命题得证
树的存储结构
a data b d e c f 0 1 2 g h i 3 4 5 6 如何找孩子结点 7 8 9 0 a b c d e f g h i 0号单元不用或 存结点个数 parent 9 0 1 1 2 2 3 5 5 5
树的存储结构
• 孩子表示法
– 多重链表:每个结点有多个指针域,分别指向其子树的根 » 结点同构:结点的指针个数相等,为树的度D » 结点不同构:结点指针个数不等,为该结点的度d
A A B D L R D D C L R D B L R D L R D
C
后序遍历序列: D B C A
二叉树的遍历
+ a b c 先序遍历: 中序遍历: 后序遍历: 层次遍历: * d / e f
- + a* b - c d / ef a+ b * c - d - e/ f ab c d - * + ef / - + / a* ef b- cd
树的存储结构
• 双亲表示法
– 实现:定义结构数组存放树的结点,每个结点含两个域: » 数据域:存放结点本身信息 » 双亲域:指示本结点的双亲结点在数组中位置 – 特点:找双亲容易,找孩子难
typedef struct node { datatype data; int parent; }JD; JD t[M];
data data child1 child2 ………. childD degree child1 child2 ………. childd
孩子链表:每个结点的孩子结点用单链表存储,再用含n个元素的 结构数组指向每个孩子链表 孩子结点:typedef struct node { int child; //该结点在表头数组中下标 struct node *next; //指向下一孩子结点 }JD; 表头结点:typedef struct tnode { datatype data; //数据域 struct node *fc; //指向第一个孩子结点 }TD; TD t[M]; //t[0]不用
树的遍历
A B C D
E
F
G J K
H L M
I
N 先序遍历:
O
A B E F I GC D H J K L N OM F G B C JK N O L M H D A
后序遍历: E I 层次遍历:
A B C D E F G H I J K L MN O
二叉树的遍历
• 方法
– 先序遍历:先访问根结点,然后分别先序遍历左子树、右子树 – 中序遍历:先中序遍历左子树,然后访问根结点,最后中序 遍历右子树 – 后序遍历:先后序遍历左、右子树,然后访问根结点 – 按层次遍历:从上到下、从左到右访问各结点
证明:n1为二叉树T中度为1的结点数 因为:二叉树中所有结点的度均小于或等于2 所以:其结点总数n=n0+n1+n2 又二叉树中,除根结点外,其余结点都只有一个 分支进入 设B为分支总数,则n=B+1 又:分支由度为1和度为2的结点射出,∴B=n1+2n2 于是,n=B+1=n1+2n2+1=n0+n1+n2 ∴n0=n2+1
总结
树的定义以及基本术语 二叉树的定义及相关的5个特性 树4种存储结构与二叉树的3种存储结 构 树与二叉树的前序,中序,后序,层次遍 历
作业
已知一棵二叉树的先根序遍历序列 为ABDGCEHF,中根序遍历序列为 BGDAEH CF,试画出该二叉树。 已知一棵二叉树的后根序遍历序列 为GDEBHFCA,中根序遍历序列为 DGBEAF HC,试画出该二叉树 。
a b d f e g c 1 2 3 a b c 4 d 5 e 6 0 7 0 8 0 9 10 11 0 f g
二叉树的存储结构
• 链式存储结构
– 二叉链表
typedef struct node { datatype data; struct node *lchild, *rchild; }JD; A B C E G D F ^ G ^ ^ C ^ E D lchild data rchild A B ^
树的遍历
– 树的遍历
• 遍历——按一定规律走遍树的各个顶点,且使每一顶点 仅被访问一次,即找一个完整而有规律的走法,以得到 树中所有结点的一个线性排列 • 常用方法
– 先根(序)遍历:先访问树的根结点,然后依次先根遍历根的 每棵子树 – 后根(序)遍历:先依次后根遍历每棵子树,然后访问根结点 – 按层次遍历:先访问第一层上的结点,然后依次遍历第二 层,……第n层的结点
A
B E K 子树 L F
C G H M
D I J
树的相关术语
– 基本术语
• 结点(node)——表示树中的元素,包括数据项及若干 指向其子树的分支 • 结点的度(degree)——结点拥有的子树数 • 叶子(leaf)——度为0的结点 • 孩子(child)——结点子树的根称为该结点的孩子 • 双亲(parents)——孩子结点的上层结点叫该结点的~ • 兄弟(sibling)——同一双亲的孩子 • 树的度——一棵树中最大的结点度数 • 结点的层次(level)——从根结点算起,根为第一层, 它的孩子为第二层…… • 深度(depth)——树中结点的最大层次数 • 森林(forest)——m(m≥0)棵互不相交的树的集合
二叉树性质
• 满二叉树 一棵深度为 k且有2 k − 1个结点的二叉树称为
– 定义:
特点:每一层上的结点数都是最大结点数
完全二叉树
定义:深度为k,有n个结点的二叉树当且仅当其每一个结点都与深 度为k的满二叉树中编号从1至n的结点一一对应时,称为~ 特点 叶子结点只可能在层次最大的两层上出现 对任一结点,若其右分支下子孙的最大层次为l,则其左分支下 子孙的最大层次必为l 或l+1 性质 性质4: 具有 个结点的完全二叉树的 n 深度为 n +1 log
D I
树的深度:4
结点F,G为堂兄弟 结点A是结点F,G的祖先
二叉树
– 定义
• 定义:二叉树是n(n≥0)个结点的有限集,它或为空树 (n=0),或由一个根结点和两棵分别称为左子树和右子 树的互不相交的二叉树构成 • 特点
– 每个结点至多有二棵子树(即不存在度大于2的结点) – 二叉树的子树有左、右之分,且其次序不能任意颠倒
性质2:深度为k的二叉树至多有2 k − 1 个结点(k≥1)
证明:由性质1,可得深度为k 的二叉树最大结点数是
(第i层的最大结点数 ) = ∑ 2 i −1 = 2 k − 1 ∑
i =1 i =1
k
k
二叉树性质
性质3:对任何一棵二叉树T,如果其终端结点数为n0, 度为2的结点数为n2,则n0=n2+1
– 有且仅有一个特定的结点,称为树的根(root) – 当n>1时,其余结点可分为m(m>0)个互不相交的有限集 T1,T2,……Tm,其中每一个集合本身又是一棵树,称为根的 子树(subtree)
• 特点:
– 树中至少有一个结点——根 – 树中各子树是互不相交的集合
树的定义
只有根结点的树
A 根
有子树的树
树的存储结构
• 孩子兄弟表示法(二叉树表示法)
– 实现:用二叉链表作树的存储结构,链表中每个结点的两个 指针域分别指向其第一个孩子结点和下一个兄弟结点 – 特点 typedef struct node » 操作容易 { datatype data; struct node *fch, *nsib; » 破坏了树的层次
二叉树
回顾
1.理解队列原理
2.掌握队列的基本操作
2
本次课程内容
树的定义及术语 二叉树的定义及基本概念 (重点) 树与二叉树的存储结构 树与二叉树的遍历 (重点)
树的定义
树是一类重要的非线性数据结构,是以分支关 系定义的层次结构 – 定义
• 定义:树(tree)是n(n>0)个结点的有限集T,其中:
}JD; a b ^ c d d ^ e f ^ ^ g g ^ h ^ i ^ h ^ i ^ b ^ e a c f
二叉树的存储结构
• 顺序存储结构
– 实现:按满二叉树的结点层次编号,依次存放二叉树中的数 据元素 – 特点: » 结点间关系蕴含在其存储位置中 » 浪费空间,适于存满二叉树和完全二叉树

2
二Leabharlann 树性质1 2 4 8 9 10 5 11 1 1 2 4 8 9 10 5 11 12 6 3 7 2 4 5 3 6 12 6 13 14 3 7 15 4 6 2 5 7 1 3
二叉树性质
» 性质5:如果对一棵有n个结点的完全二叉树的结点按层序编号, 则对任一结点i(1≤i≤n),有: (1) 如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其 双亲是i/2 (2) 如果2i>n,则结点i无左孩子;如果2i≤n,则其左孩子是2i (3) 如果2i+1>n,则结点i无右孩子;如果2i+1≤n,则其右孩子 是2i+1
相关文档
最新文档