【数据结构】二叉树——链式结构(下)

简介: 【数据结构】二叉树——链式结构(下)

3.2 叶子节点个数

代码1:

1. void BTreeLeafSize(BTNode* root, int* pcount)
2. {
3.  if (root == NULL)
4.  {
5.    return;
6.  }
7.  if ((root->left == NULL) && (root->right == NULL))
8.  {
9.    (*pcount)++;
10.   }
11.   BTreeLeafSize(root->left, pcount);
12.   BTreeLeafSize(root->right, pcount);
13. }
1. int main()
2. {
3. int count = 0;
4. BTreeLeafSize(tree, &count);
5.  printf("%d\n", count);
6.  return 0;
7. }

思路1:遍历+计数【代码1】

代码2:

1. int BTreeLeafSize(BTNode* root)
2. {
3.  if (root == NULL)
4.  {
5.    return 0;
6.  }
7.  if (root->right == NULL && root->left == NULL)
8.  {
9.    return 1;
10.   }
11.   return BTreeLeafSize(root->right) + BTreeLeafSize(root->left);
12. }
1. int main()
2. {
3. BTreeLeafSize(tree);
4.  printf("%d\n", BTreeLeafSize(tree));
5.  return 0;
6. }

思路2:分治【代码2】

数的叶子节点等于左子树的叶子节点+右子树的叶子节点。一直分到这个小树的根的节点不等于NULL,但是左右子树为NULL。

3.3 第k层节点个数

1. int BTreeKLevelSize(BTNode* root, int k)
2. {
3.  assert(k >= 1);
4.  if (root == NULL)
5.  {
6.      return 0;
7.  }
8.  if (k == 1)
9.  {
10.     return 1;
11.   }
12.   return  BTreeKLevelSize(root->left, k - 1) + BTreeKLevelSize(root->right, k - 1);
13. }

分治思想:(1)空树,返回0(2)非空,且k==1,返回1(3)非空且K>1,装换成左子树K-1层节点个数+右子树k-1层节点个数。

即:【首先,求第k层节点个数,首先这一层看成满的,如果有节点就返回1,如果没有节点就返回0】其次(1)如果求的是第一层的节点个数,那就直接是1,(2)如果求的是第二层的节点个数,那么可以转化成求左子树的第一层节点个数+右子树的第一层节点个数(3)如果求的是根的第三层的节点个数,那么可以转化成求该根左子树的第二层节点个数+右子树的第二层节点个数,再转化成该根的左子树的左子树的第一层节点个数+该根左子树的右子树的第一层节点个数+根的右子树的左子树的第一层节点个数+该根右子树的右子树的第一层节点个数【第一层(1)空树,返回0(2)k==1,返回1】

3.4 二叉树的高度/深度

1. int BTreeDepth(BTNode* root)
2. {
3.  if (root == NULL)
4.  {
5.    return 0;
6.  }
7.  return  BTreeDepth(root->left) > BTreeDepth(root->right) ? (BTreeDepth(root->left) + 1) : (BTreeDepth(root->right) + 1);
8. }

分治思想:左子树和右子树高度较大的那一个+1.

3.5 查找值为x的节点

1. BTNode* BTreeFind(BTNode* root, BTDataType x)
2. {
3.  if (root == NULL)
4.  {
5.    return NULL;
6.  }
7.  if (root->data == x)
8.  {
9.    return root;
10.   }
11.   BTNode* ret1 = BTreeFind(root->left, x);
12.   if (ret1)
13.   {
14.     return ret1;
15.   }
16.   BTNode* ret2 = BTreeFind(root->right, x);
17.   if (ret2)
18.   {
19.     return ret2;
20.   }
21.   return NULL;
22. }

分治思想:【如果左子树找到了,那么右子树就不需要再进行查找】

找到了指针,就可以对其进行改变值

四、二叉树的创建和销毁

4.1 构建二叉树

链接:牛客

代码:

1. #include <stdio.h>
2. #include <stdlib.h>
3. typedef struct BinaryTreeNode
4. {
5. char data;
6. struct BinaryTreeNode* left;
7. struct BinaryTreeNode* right;
8. }BTNode;
9. //先构建一个二叉树【前序遍历】
10. BTNode* CreatTree(char* a, int* pi)
11.  {
12. if (a[*pi] == '#')
13.     {
14.         (*pi)++;
15. return NULL;
16.     }
17. //先构建根
18.     BTNode* root = (BTNode*)malloc(sizeof(BTNode));
19.     root->data = a[*pi];
20.     (*pi)++;
21. //再构建左子树和右子树
22.     root->left = CreatTree(a, pi);
23.     root->right = CreatTree(a, pi);
24. return root;
25.  }
26. 
27. void InOrder(BTNode* root)
28. {
29. if (root == NULL)
30.     {
31. return;
32.     }
33. InOrder(root->left);
34. printf("%c ", root->data);
35. InOrder(root->right);
36. }
37. 
38. int main()
39. {
40. char a[100];
41. scanf("%s", a);
42. int i = 0;
43.     BTNode* tree = CreatTree(a, &i);
44. InOrder(tree);
45. free(tree);
46.     tree = NULL;
47. return 0;
48. }

思想:先序遍历的思想的字符串,建立二叉树【遇到'#',就返回NULL】,然后再中序遍历的思想进行打印。

4.2 二叉树销毁

1. void BTreeDestory(BTNode* root)
2. {
3.  if (root == NULL)
4.  {
5.    return;
6.  }
7.  BTreeDestory(root->left);
8.  BTreeDestory(root->right);
9.  free(root);
10. }
11. int main()
12. {
13.   BTNode* tree = CreatBinaryTree();
14.   BTreeDestory(tree);//想改变谁的内容,就需要把谁的地址传递给函数。
15.   free(tree);
16.   tree = NULL;
17.   return 0;
18. }

(1)后序遍历(2)一级指针,tree需要在函数外面进行销毁。(3)如果传递的是二级指针,就可以在函数内进行销毁。

4.3 判断二叉树是否为完全二叉树

1. bool BinaryTreeComplete(BTNode* root)
2. {
3.  Queue q;
4.  QueueInit(&q);
5.  if (root)
6.  {
7.    QueuePush(&q, root);
8.  }
9.  while (!QueueEmpty(&q))
10.   {
11.     BTNode* front = QueueFront(&q);
12.     if (front == NULL)
13.     {
14.       break;
15.     }
16.     QueuePop(&q);
17.     QueuePush(&q, root->left);//不管是还是不是NULL,都进入队列
18.     QueuePush(&q, root->right);
19.   }
20.   while (!QueueEmpty(&q))
21.   {
22.     BTNode* front = QueueFront(&q);
23.     if (front != NULL)
24.     {
25.       QueueDestory(&q);
26.       return false;
27.     }
28.     QueuePop(&q);
29.   }
30.   QueueDestory(&q);
31.   return true;
32. }

思想:层序遍历的思想;一个节点出队列的时候,会把该节点下一层的节点入队列(把NULL也进入队列),完全二叉树,层序遍历完之后,就不会出现NULL。如果不是完全二叉树,就会出现NULL。

思路:(1)层序遍历,空节点也可以进队列(2)出到空节点以后,出队列中所有数据,如果全是NULL,就是完全二叉树,如果有非空,就不是完全二叉树。

注意:返回数据之前,要把队列给销毁【否则会出现内存泄漏】

相关文章
|
4天前
|
存储 搜索推荐 算法
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
43 16
|
4天前
|
C语言
【数据结构】二叉树(c语言)(附源码)
本文介绍了如何使用链式结构实现二叉树的基本功能,包括前序、中序、后序和层序遍历,统计节点个数和树的高度,查找节点,判断是否为完全二叉树,以及销毁二叉树。通过手动创建一棵二叉树,详细讲解了每个功能的实现方法和代码示例,帮助读者深入理解递归和数据结构的应用。
32 8
|
27天前
|
存储 算法 关系型数据库
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
这篇文章主要介绍了多路查找树的基本概念,包括二叉树的局限性、多叉树的优化、B树及其变体(如2-3树、B+树、B*树)的特点和应用,旨在帮助读者理解这些数据结构在文件系统和数据库系统中的重要性和效率。
16 0
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
|
27天前
|
存储 算法 搜索推荐
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
这篇文章主要介绍了顺序存储二叉树和线索化二叉树的概念、特点、实现方式以及应用场景。
17 0
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
|
29天前
|
Java
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(二)
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(二)
25 1
|
29天前
|
算法 Java C语言
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(一)
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(一)
23 1
|
1月前
|
存储
【数据结构】二叉树链式结构——感受递归的暴力美学
【数据结构】二叉树链式结构——感受递归的暴力美学
|
27天前
|
存储 算法
探索数据结构:分支的世界之二叉树与堆
探索数据结构:分支的世界之二叉树与堆
|
27天前
探索顺序结构:栈的实现方式
探索顺序结构:栈的实现方式
|
27天前
|
存储 算法
数据结构与算法学习十六:树的知识、二叉树、二叉树的遍历(前序、中序、后序、层次)、二叉树的查找(前序、中序、后序、层次)、二叉树的删除
这篇文章主要介绍了树和二叉树的基础知识,包括树的存储方式、二叉树的定义、遍历方法(前序、中序、后序、层次遍历),以及二叉树的查找和删除操作。
22 0