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

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

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,就是完全二叉树,如果有非空,就不是完全二叉树。

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

相关文章
|
8天前
【数据结构】二叉树(遍历,递归)
【数据结构】二叉树(遍历,递归
15 2
|
4天前
【数据结构】二叉树的三种遍历(非递归讲解)
【数据结构】二叉树的三种遍历(非递归讲解)
7 1
|
4天前
|
存储
【数据结构】二叉树相关oj题(一)
【数据结构】二叉树相关oj题(一)
9 1
|
7天前
|
存储 分布式数据库
[数据结构]~二叉树
[数据结构]~二叉树
|
8天前
|
C语言
【C语言/数据结构】二叉树(层序遍历|判断完全二叉树|性质)
【C语言/数据结构】二叉树(层序遍历|判断完全二叉树|性质)
279 52
|
8天前
【数据结构】二叉树-堆(top-k问题,堆排序,时间复杂度)
【数据结构】二叉树-堆(top-k问题,堆排序,时间复杂度)
16 4
|
8天前
【数据结构】二叉树-堆(函数实现)
【数据结构】二叉树-堆(函数实现)
12 2
|
8天前
|
存储 分布式数据库
【数据结构】树和二叉树堆(基本概念介绍)
【数据结构】树和二叉树堆(基本概念介绍)
22 6
|
13天前
|
机器学习/深度学习 分布式数据库
数据结构第六课 -----链式二叉树的实现
数据结构第六课 -----链式二叉树的实现
|
13天前
|
存储 算法 分布式数据库
数据结构第五课 -----二叉树的代码实现
数据结构第五课 -----二叉树的代码实现