手撕二叉树

news2025/6/6 23:25:24

前序遍历构建二叉树

二叉树的销毁

二叉树的结点个数

二叉树叶子节点个数

二叉树第k层节点个数

二叉树查找值为x的节点

二叉树前序遍历 

二叉树中序遍历

二叉树后序遍历

二叉树的层序遍历

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

完整代码

test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>

typedef int BTDataType;

typedef struct BinaryTreeNode
{
	struct  BinaryTreeNode* left;
	struct  BinaryTreeNode* right;
	BTDataType val;
}BTNode;

#include "Queue.h"

// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int* pi)
{
	if (a[*pi] == -1)
	{
		++(*pi);
		return NULL;
	}

	BTNode* root = (BTNode*)malloc(sizeof(BTNode));
	root->val = a[*pi];
	++(*pi);

	root->left = BinaryTreeCreate(a, pi);
	root->right = BinaryTreeCreate(a, pi);
	return root;
}

 //二叉树销毁
void BinaryTreeDestory(BTNode** root)
{
	if (*root == NULL)
	{
		return;
	}
	BinaryTreeDestory(&(*root)->left);
	BinaryTreeDestory(&(*root)->right);
	free(*root);
	*root = NULL;
}

// 二叉树节点个数
int BinaryTreeSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}

	return BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}

	if (root->left == NULL && root->right == NULL)
	{
		return 1;
	}

	return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}

// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k)
{
	if (root == NULL)
	{
		return 0;
	}

	if (k == 1)
	{
		return 1;
	}

	return BinaryTreeLevelKSize(root->left, k-1) + BinaryTreeLevelKSize(root->right, k-1);
}

// 二叉树前序遍历 
void BinaryTreePrevOrder(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}

	printf("%d ", root->val);
	BinaryTreePrevOrder(root->left);
	BinaryTreePrevOrder(root->right);
}

// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)
	{
		return NULL;
	}

	if (root->val == x)
	{
		return root;
	}

	BTNode* ret = NULL;
	ret = BinaryTreeFind(root->left, x);
	if (ret)
	{
		return ret;
	}
	ret = BinaryTreeFind(root->right, x);
	if (ret)
	{
		return ret;
	}

	return NULL;
}

// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}

	BinaryTreeInOrder(root->left);
	printf("%d ", root->val);
	BinaryTreeInOrder(root->right);
}

// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}

	BinaryTreePostOrder(root->left);
	BinaryTreePostOrder(root->right);
	printf("%d ", root->val);
}

// 层序遍历
void BinaryTreeLevelOrder(BTNode* root)
{
	Que q;
	QueueInit(&q);

	if (root)
	{
		QueuePush(&q, root);
	}

	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);

		if (front->left)
		{
			QueuePush(&q, front->left);
		}
		if (front->right)
		{
			QueuePush(&q, front->right);
		}

		QueuePop(&q);
		printf("%d ", front->val);
	}
	QueueDestroy(&q);
}

// 判断二叉树是否是完全二叉树
bool BinaryTreeComplete(BTNode* root)
{
	Que q;
	QueueInit(&q);

	if (root)
	{
		QueuePush(&q, root);
	}

	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		if (front == NULL)
		{
			break;
		}
		QueuePush(&q, front->left);
		QueuePush(&q, front->right);
		QueuePop(&q);
	}

	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);

		if (front != NULL)
		{
			QueueDestroy(&q);
			return false;
		}
	}
	QueueDestroy(&q);
	return true;
}

int main()
{
	int a[] = { 1,3,5,-1,-1,2,-1,-1,1,-1,1,-1,-1 };
	int j = 0;
	BTNode* root=BinaryTreeCreate(a, &j);
	bool x = BinaryTreeComplete(root);
	printf("%d", x);
	return 0;
}

Queue.h

#pragma once

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

typedef struct BinaryTreeNode* QDataType;
typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType data;
}QNode;

typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Que;

void QueueInit(Que* pq);
void QueueDestroy(Que* pq);
void QueuePush(Que* pq, QDataType x);
void QueuePop(Que* pq);
QDataType QueueFront(Que* pq);
QDataType QueueBack(Que* pq);
bool QueueEmpty(Que* pq);
int QueueSize(Que* pq);

Queue.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "Queue.h"

void QueueInit(Que* pq)
{
	assert(pq);

	pq->head = pq->tail = NULL;
	pq->size = 0;
}

void QueueDestroy(Que* pq)
{
	assert(pq);

	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}

	pq->head = pq->tail = NULL;
	pq->size = 0;
}

void QueuePush(Que* pq, QDataType x)
{
	assert(pq);

	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}

	newnode->data = x;
	newnode->next = NULL;

	if (pq->tail == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}

	pq->size++;
}

void QueuePop(Que* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}

	pq->size--;
}

QDataType QueueFront(Que* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->head->data;
}

QDataType QueueBack(Que* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->tail->data;
}

bool QueueEmpty(Que* pq)
{
	assert(pq);

	return pq->head == NULL;
}

int QueueSize(Que* pq)
{
	assert(pq);

	return pq->size;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1027275.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络防御--防火墙

拓扑 Cloud 1 作为电脑与ENSP的桥梁 防火墙配置 登录防火墙 配置IP地址及安全区域 添加地址对象 配置策略 1、内网可以访问服务器 结果 2、内网可以访问公网 结果 配置NAT策略 结果

注入之SQLMAP(工具注入)

i sqlmap是一个自动化的SQL注入工具&#xff0c;其主要功能是扫描&#xff0c;发现并利用给定的URL和SQL注入漏洞&#xff0c;其广泛的功能和选项包括数据库指纹&#xff0c;枚举&#xff0c;数据库提权&#xff0c;访问目标文件系统&#xff0c;并在获取操作权限时执行任…

【Java 基础篇】Java多线程编程详解:线程创建、同步、线程池与性能优化

Java是一门强大的编程语言&#xff0c;其中最引人注目的特性之一是多线程支持。多线程允许我们在同一程序中同时执行多个任务&#xff0c;这大大提高了应用程序的性能和响应能力。本文将深入介绍Java线程的基础知识&#xff0c;无论您是初学者还是有一些经验的开发人员&#xf…

Qt5开发及实例V2.0-第八章-Qt模型/视图结构

Qt5开发及实例V2.0-第八章-Qt模型/视图结构 第8章 Qt 5模型/视图结构8.1 概述8.1.1 基本概念8.1.2 【实例】&#xff1a;模型/视图类使用 8.2 模型&#xff08;Model&#xff09;8.3 视图&#xff08;View&#xff09;8.4 代理&#xff08;Delegate&#xff09; 本章相关例程源…

2023.9.19 关于 数据链路层 和 DNS 协议 基本知识

目录 数据链路层 MTU DNS 协议 补充 DHCP协议 数据链路层 基本概念&#xff1a; 考虑相邻两个节点之间的传输&#xff08;通过 网线 / 光纤 / 无线 直接相连的两个设备&#xff09;以太网协议 规定了 数据链路层 和 物理层 的内容 IP地址 与 mac地址 的相互配合 IP地址 描…

ardupilot的编译过程

环境 树莓派4b ubuntu20.04 git 2.25.1 python3.8.10 pixhawk2.4.8 下载源码 &#xff08;已经配置好git环境和ssh&#xff09; git clone --recurse-submodules gitgithub.com:ArduPilot/ardupilot.gitcd ardupilotgit status使用git status检查是否下载完整 如果不完整&a…

Nuxt 菜鸟入门学习笔记:路由

文章目录 路由 Routing页面 Pages导航 Navigation路由参数 Route Parameters路由中间件 Route Middleware路由验证 Route Validation Nuxt 官网地址&#xff1a; https://nuxt.com/ 路由 Routing Nuxt 的一个核心功能是文件系统路由器。pages/目录下的每个 Vue 文件都会创建一…

hadoop测试环境sqoop使用

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 Sqoop看这篇文章就够了_must contain $conditions in where clause._SoWhat1412的博客-CSDN博客 大数据环境 C:\Windows\System32\drivers\etc 修改ip和hostname的对应关系 1…

将本地项目上传至Github详解

目录 1 前言2 本地代码上传2.1 命令行方法2.2 图形界面法2.3 结果 1 前言 GitHub是一个面向开源及私有软件项目的托管平台&#xff0c;因为只支持Git作为唯一的版本库格式进行托管&#xff0c;故名GitHub 。开发者常常将github作为代码管理平台&#xff0c;方便代码存储、版本…

统计物理学复习----热力学的基本规律

General Laws of thermodynamics 热力学系统常识 单位制 1大气压强 101325 Pa 基本概念与专业英语 状态参量 pressurevolumetemperature Extensive quantityIntensive quantityMechanicalVPThermal ST Helmholtz Free EnergyEnthalpyInternal EnergyGibbs Free Energy 准…

ChunJun(OldNameIsFlinkX)

序言 ChunJun主要是基于Flink实时计算框架,封装了不同数据源之间的数据导入与导出功能.我们只需要按照ChunJun的要求提供原始与目标数据源的相关信息给Chunjun,然后它会帮我们生成能运行与Flink上的算子任务执行,这样就避免了我们自己去根据不同的数据源重新编辑读入与读出的方…

模块化开发_php中使用redis

redis 介绍和安装 redis数据库&#xff0c;支持数据持久化&#xff0c;常用与分布式锁&#xff0c;支持事务&#xff0c;持久化&#xff0c;非关心型数据库 区别&#xff1a; 关系型数据库&#xff1a;硬盘&#xff0c;安全&#xff0c;结构简单&#xff0c;易于理解,浪费空间…

Mac环境下jupyter添加nbextension插件

1、没有插件的状态 2、在窗口运行命令 pip install jupyter_contrib_nbextensions 安装成功 3、添加 jupyter contrib nbextension install --user 运行后 报错 No module named notebook.base 更新版本后再添加 pip install jupyter notebook6.1.0 jupyter contrib nb…

vim缓存-交换文件

Catf1agCTF靶场 web swp 题目链接&#xff1a;http://catf1ag.cn/ 个人博客&#xff1a;https://sword-blogs.com/ 题目考点&#xff1a; vim在编辑文档的过程中如果异常退出&#xff0c;会产生缓存文件 vim 交换文件名 参考文章&#xff1a;vim手册 https://yianwillis.…

从零学习开发一个RISC-V操作系统(二)丨GCC编译器和ELF格式

本篇文章的内容 一、GCC&#xff08;GUN Compiler Collection&#xff09;1.1 GCC的命令格式1.2 GCC的主要执行步骤1.3 GCC涉及的文件类型 二、ELF简介2.1 ELF文件格式图2.2 ELF文件处理的相关工具2.3 练习 本系列是博主参考B站课程学习开发一个RISC-V的操作系统的学习笔记&…

只需4步使用Redis缓存优化Node.js应用

介绍 通过API获取数据时&#xff0c;会向服务器发出网络请求&#xff0c;收到响应数据。但是&#xff0c;此过程可能非常耗时&#xff0c;并且可能会导致程序响应时间变慢。 我们使用缓存来解决这个问题&#xff0c;客户端程序首先向API发送请求&#xff0c;将返回的数据存储…

数据库:Hive转Presto(一)

本人因为工作原因&#xff0c;经常使用hive以及presto&#xff0c;一般是编写hive完成工作&#xff0c;服务器原因&#xff0c;presto会跑的更快一些&#xff0c;所以工作的时候会使用presto验证结果&#xff0c;所以就要频繁hive转presto&#xff0c;为了方便&#xff0c;我用…

Shader实战(2):在unity中实现物体材质随时间插值渐变

目录 前言 一、shader代码 二、材质准备 三、控制代码 前言 最近想做一个物体两套材质随时间插值渐变的效果&#xff0c;本以为可以通过unity自带的Material.Lerp()实现&#xff0c;后来发现这个方法只适用于纯色的情况&#xff0c;其实与Color.Lerp()是同样的效果&#xf…

深度分析Oracle中的NULL

【squids.cn】 全网zui低价RDS&#xff0c;免费的迁移工具DBMotion、数据库备份工具DBTwin、SQL开发工具等 关键点 特殊值NULL意味着没有数据&#xff0c;它声明了该值是未知的事实。默认情况下&#xff0c;任何类型的列和变量都可以取这个值&#xff0c;除非它们有一个NOT N…

阿里云产品试用系列-云桌面电脑

无影云电脑&#xff08;WUYING Workspace&#xff09;&#xff0c;是一种易用、安全、高效的云上桌面服务。它支持快速便捷的桌面环境创建、部署、统一管控与运维。无需前期传统硬件投资&#xff0c;帮您快速构建安全、高性能、低成本的企业桌面办公体系。可广泛应用于具有高数…