当前位置:网站首页>二叉树[全解](C语言)
二叉树[全解](C语言)
2022-08-05 00:36:00 【Obto-】
目录:
--->>二叉树基本信息
--->>二叉树的概念
--->>二叉树的性质
--->>构建二叉树
--->>二叉树的遍历
--->>二叉树的深度
--->>查找值为x的节点
--->>第k层有多少个元素
--->>叶子结点个数
--->>树的大小(元素总个数)
--->>TOP-K问题
--------------------------------------------------------------------------------------------------------------------------------
前言:本篇博客概述了二叉树的各种操作,希望对复习的同学有一定帮助,也希望大家多多指教
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-===-=-=-=-=-=-=-=-=-=-=-=-=---=-=-=-=-=-=-=-=-=-=-=
二叉树基本信息
1.二叉树是一种重要的非线性数据结构,直观地看,它是数据元素(在树中称为结点)按分支关系组织起来的结构,很象自然界中的树那样
2.二叉树是每个节点最多只有两个字数的有序数,通常子树的根称作 "左子树" 和"右子树":如图中‘C’为左子树‘D’为右子树
二叉树的概念
1.一个二叉树的结点是一个有限的集合
①要么 该集合为空
②要么 该集合由一个根节点加上两颗别称为左子树和右子树的二叉树组成
2.完全二叉树:完全二叉树是一种效率很高的数据结构,完全二叉树是由满二叉树引出来的
3.满二叉树就是所有的结点都有两个子结点,完全二叉树是叶结点上是连续的 ,中间是不可以有断开的
二叉树的性质
1.若规定根结点为1,则一颗非空二叉树的第 i 层上最多有2^(i-1).
2.若规定根结点为1,则深度为h的二叉树的最大节点数是2^h-1
3.对任何一颗二叉树;如果度为0的叶结点个数为n0,度为2的分支结点个数为n2则n0=n2+1
4.若规定根结点为1,具有n个结点满二叉树的深度 h=log2(n+1)
5.计算下标父子间的关系 leftchildren = parent*2+1 rightchildren = parent*2+2 parent=(child-1)/2
构建二叉树
1.定义二叉树的结构
typedef int HPDataType;
typedef struct {
int data;
struct BTNode* left;
struct BTNode* right;
}BTNode;
2.创建结点的函数
BTNode* BuyNode(int x)
{
BTNode* node = (BTNode*)malloc(sizeof(BTNode));
assert(node);
node->data = x;
node->left = node->right = NULL;
return node;
}
3.链接二叉树
BTNode* node1 = BuyNode(1);
BTNode* node2 = BuyNode(2);
BTNode* node3 = BuyNode(3);
BTNode* node4 = BuyNode(4);
BTNode* node5 = BuyNode(5);
BTNode* node6 = BuyNode(6);
node1->left = node2;
node1->right = node4;
node2->left = node3;
node4->left = node5;
node4->right = node6;
二叉树的遍历
前序遍历:
遍历顺序是先访问根结点后访问左结点,最后访问右结点
void Preorder(BTNode* root)
{
if (root == NULL)
{
printf("# ");
return;
}
printf("%d ", root->data);
Preorder(root->left);
Preorder(root->right);
}
中序遍历:
遍历顺序是先访问左结点后访问根结点,最后访问右结点
void Preorder(BTNode* root)
{
if (root == NULL)
{
printf("# ");
return;
}
Preorder(root->left);
printf("%d ", root->data);
Preorder(root->right);
}
后序遍历:
遍历顺序是先访问左结点后访问右结点,最后访问根结点
void Preorder(BTNode* root)
{
if (root == NULL)
{
printf("# ");
return;
}
Preorder(root->left);
Preorder(root->right);
printf("%d ", root->data);
}
层序遍历:
void LevelOrder(BTNode* root)
{
Queue q; //定义一个队列名字叫做q
QueueInit(&q); //初始化队列
if (root)
{
QueuePush(&q,root); //将数顶入队列
}
while (!QueueEmpty(&q)) //当队列为空时结束循环
{
BTNode* front = QueueFront(&q);//保存树顶指针
printf("%d ", front->data);
QueuePop(&q); //出队头
if (front->left != NULL) //入左子树
{
QueuePush(&q, front->left);
}
if (front->right != NULL) //入右子树
{
QueuePush(&q, front->right);
}
}
printf("\n");
QueueDestory(&q); //队列的销毁
}
二叉树的深度
int TreeDepth(BTNode* node)
{
if (node == NULL)
return 0;
if (TreeDepth(node->left) > TreeDepth(node->right))
return TreeDepth(node->left) + 1;
else
return TreeDepth(node->right) + 1;
}
查找值为x的节点
BTNode* TreeFind(BTNode* node, int x)
{
if (node == NULL)
return;
if (node->data == x)
return node;
TreeFind(node->left,x);
TreeFind(node->right,x);
return NULL;
}
第k层有多少个元素
int TreeKLevel(BTNode* node , int k)
{
if (node == NULL)
return 0;
if (k == 1)
return 1;
return TreeKLevel(node->left, k - 1) + TreeKLevel(node->right, k - 1) ;
}
叶子结点个数
int TreeLeafSize(BTNode* node)
{
if (node == NULL)
return 0;
if (node->left == NULL && node->right == NULL)
{
return 1;
}
return TreeLeafSize(node->left) + TreeLeafSize(node->right);
}
树的大小(元素总个数)
int TreeSize(BTNode* node)
{
if (node == NULL)
return 0;
else {
return TreeSize(node->left) + TreeSize(node->right) + 1;
}
}
TOP-K问题
TOP-K问题:即求数据结合中前K个最大的元素或者最小的元素,一般情况下数据量都比较大
比如:世界500强,国服前200
对于TOP-K问题,最简单直接的方式就是排序,但是如果数据量特别大,排序就不可取了,最佳的方式就是用堆来解决
那么就设计到一个问题,如果保持堆中k个数都是总数据中最小的呢,这时候就要对堆进行插入并t调整
①向上调整
void AdjustUp(HPDataType * a,int child)
{
int parent = (child - 1) / 2;
while (child > 0)
{
if (a[child] < a[parent])
{
swap(&a[child], &a[parent]);
child = parent;
parent = (child - 1) / 2;
}
else {
break;
}
}
}
②向下调整
void AdjustDown(HPDataType* a, int size, int parent)
{
int child = parent * 2 + 1;
while (child < size)
{
if (child + 1 < size && a[child + 1] < a[child])
{
++child;
}
if (a[child] < a[parent])
{
swap(&a[child], &a[parent]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
TOP-K的实现代码
void PrintTopk(int *a,int n,int k)
{
int* heap = (int*)malloc(sizeof(int) * k);
//先将前k个数据导入数组
for (int i = 0; i < k; i++)
{
heap[i] = a[i];
}
//将k个数据建堆
for (int i = (k - 1 - 1) / 2; i >= 0; i--)//二叉树的最后一行不需要进行向下调整
{
AdjustDown(heap, k, i);
}
/*for (int i = 1; i < k; i++)
{
AdjustUp(heap, i);
}*/
for (int j = k; j < n; j++)
{
if (a[j] > heap[0])
{
heap[0] = a[j];
AdjustDown(heap, k, 0);
}
}
for (int i = 0; i < k; i++)
printf("%d ", heap[i]);
}
边栏推荐
- 软件测试面试题:什么是软件测试?软件测试的目的与原则?
- 2022 Nioke Multi-School Training Session H Question H Take the Elevator
- oracle创建用户以后的权限问题
- tiup uninstall
- Software testing interview questions: What stages should a complete set of tests consist of?
- 机器学习(公式推导与代码实现)--sklearn机器学习库
- 软件质量评估的通用模型
- 【idea】idea配置sql格式化
- tiup telemetry
- tiup update
猜你喜欢
[FreeRTOS] FreeRTOS and stm32 built-in stack occupancy
倒计时1天!8月2日—4日与你聊聊开源与就业那些事!
STC89C52RC的P4口的应用问题
gorm联表查询-实战
简单的顺序结构程序(C语言)
【FreeRTOS】FreeRTOS与stm32内置堆栈的占用情况
After the staged testing is complete, have you performed defect analysis?
redis可视化管理软件Redis Desktop Manager2022
TinyMCE disable escape
英特尔WiFi 7产品将于2024年亮相 最高速度可达5.8Gbps
随机推荐
标识符、关键字、常量 和变量(C语言)
leetcode:269. 火星词典
BC(转)[js]js计算两个时间相差天数
About I double-checked and reviewed the About staff page, returning an industry question
软件测试面试题:手工测试与自动测试有哪些区别?
刘润直播预告 | 顶级高手,如何创造财富
2022 Multi-school Second Session K Question Link with Bracket Sequence I
TinyMCE disable escape
QSunSync 七牛云文件同步工具,批量上传
软件测试面试题:请你分别画出 OSI 的七层网络结构图和 TCP/IP 的四层结构图?
Software testing interview questions: Have you used some tools for software defect (Bug) management in your past software testing work? If so, please describe the process of software defect (Bug) trac
2022 Hangzhou Electric Power Multi-School Session 3 Question L Two Permutations
僵尸进程和孤儿进程
克服项目管理中恐惧心理
2022牛客多校训练第二场 L题 Link with Level Editor I
2022 Hangzhou Electric Power Multi-School Session 3 Question B Boss Rush
lua 如何 实现一个unity协程的工具
uinty lua 关于异步函数的终极思想
《MySQL入门很轻松》第2章:MySQL管理工具介绍
matlab中rcosdesign函数升余弦滚降成型滤波器