手撕算法题4(附思路和源码)

news2024/9/28 21:27:05

算法

  • 1.单值二叉树
  • 2.相同的树
  • 3.另一棵树的子树
  • 4.二叉树的前序遍历
  • 5.二叉树的中序遍历
  • 6.二叉树的后序遍历
  • 7.二叉树遍历
  • 8.TopK问题

1.单值二叉树

在这里插入图片描述
单值二叉树

思路
比较父节点和子结点,相同返回true,否则返回false,递归


设计程序
若结点为空返回true
遍历左子树和右子树,左子树中子结点和父节点相同且右子树中子结点和父子树相同返回true,其余全部返回false

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
 typedef struct TreeNode TreeNode;
bool isUnivalTree(struct TreeNode* root) {
    if(root==NULL)
    return true;
    if(root->left&&root->val!=root->left->val)
    return false;
    if(root->right&&root->val!=root->right->val)
    return false;
    return isUnivalTree(root->left)&&isUnivalTree(root->right);
}

不能以相同返回为真去判断,这样的话只遍历到根结点就会直接返回true了


2.相同的树

在这里插入图片描述
相同的树

思路
比较两个二叉树结点的值,不同返回false

设计程序
若两个结点同时为空返回true,其中一个为空返回false,都不为空则比较结点的值不同返回false,递归的遍历两个二叉树的左子树且右子树

编写代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
    if(p==NULL&&q==NULL)
    return true;
    if(p==NULL||q==NULL)
    return false;
    if(p->val!=q->val)
    return false;
    return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
}

在这里插入图片描述
对称二叉树

比较根节点的左子树和右子树是否相同,利用上题相同的树的接口

编写程序
直接调用相同的树函数,不过注意这里是对称不是相同,比较的结点是左子树的左结点和右子树的右结点且左子树的右结点且右子树的左结点

编写代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
 bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
    if(p==NULL&&q==NULL)
    return true;
    if(p==NULL||q==NULL)
    return false;
    if(p->val!=q->val)
    return false;
    return isSameTree(p->left,q->right)&&isSameTree(p->right,q->left);
}

bool isSymmetric(struct TreeNode* root) {
    return isSameTree(root->left,root->right);
}

3.另一棵树的子树

在这里插入图片描述
另一棵树的子树

思路
借用相同的树的代码遍历所有子树


设计程序
比较根节点和子树,比较根节点的左子树与子树或根节点的右子树与子树


编写代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
    if(p==NULL&&q==NULL)
    return true;
    if(p==NULL||q==NULL)
    return false;
    if(p->val!=q->val)
    return false;
    return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
}
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){
    if(root==NULL)
    return false;
    if(isSameTree(root,subRoot))
    return true;
    return isSubtree(root->left,subRoot)||isSubtree(root->right,subRoot);
}

这里的话有些同学可能想当然return isSameTree(root->left,subRoot) || isSameTreeroot->right,subRoot);但其实这样的话只比较了层数为1和2的子树


4.二叉树的前序遍历

在这里插入图片描述
二叉树的前序遍历

思路 前序遍历,存放到数组中

设计程序
先确定数组大小封装一个求二叉树结点多少的接口,动态开辟相应大小的数组,前序遍历(单独封装)存放到数组中

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
 typedef struct TreeNode TreeNode;
 int BinaryTreeSize(TreeNode*root)
 {
    if(root==NULL)
    return 0;
    return 1+BinaryTreeSize(root->left)+BinaryTreeSize(root->right);
 }
 void _preorderTraversal(struct TreeNode* root, int* arr,int*pi) {
    if(root==NULL)
    return;
    arr[(*pi)++]=root->val;
    _preorderTraversal(root->left,arr,pi);
    _preorderTraversal(root->right,arr,pi);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize) {
    *returnSize=BinaryTreeSize(root);
    int*returnArr=(int*)malloc(sizeof(int)*(*returnSize));
    int i=0;
    _preorderTraversal(root,returnArr,&i);
    return returnArr;
}

这里要传址调用否则形参是实参的临时拷贝,函数调用完就销毁了


5.二叉树的中序遍历

在这里插入图片描述
二叉树的中序遍历

思路设计基本一致
编写代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
 typedef struct TreeNode TreeNode;
 int BinaryTreeSize(TreeNode*root)
 {
    if(root==NULL)
    return 0;
    return 1+BinaryTreeSize(root->left)+BinaryTreeSize(root->right);
 }
 void __inorderTraversal(struct TreeNode* root, int*arr,int* pi)
 {
    if(root==NULL)
    return;
    __inorderTraversal(root->left,arr,pi);
    arr[(*pi)++]=root->val;
     __inorderTraversal(root->right,arr,pi);
 }
int* inorderTraversal(struct TreeNode* root, int* returnSize) {
    *returnSize=BinaryTreeSize(root);
    int*returnArr=(int*)malloc(sizeof(int)*(*returnSize));
    int i=0;
    __inorderTraversal(root,returnArr,&i);
    return returnArr;
    
}

6.二叉树的后序遍历

在这里插入图片描述
二叉树的后序遍历

插入代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
 typedef struct TreeNode TreeNode;
 int BinaryTreeSize(TreeNode*root)
 {
    if(root==NULL)
    return 0;
    return 1+BinaryTreeSize(root->left)+BinaryTreeSize(root->right);
 }
 void __postorderTraversal(struct TreeNode* root, int*arr,int* pi)
 {
    if(root==NULL)
    return;
    __postorderTraversal(root->left,arr,pi);
    __postorderTraversal(root->right,arr,pi);
     arr[(*pi)++]=root->val;
 }
int* postorderTraversal(struct TreeNode* root, int* returnSize) {
    *returnSize=BinaryTreeSize(root);
    int*returnArr=(int*)malloc(sizeof(int)*(*returnSize));
    int i=0;
    __postorderTraversal(root,returnArr,&i);
    return returnArr;
}

7.二叉树遍历

在这里插入图片描述

思路如题

设计程序
创建字符数组读取字符串(还好这里#代表空格否则根本读不全),前序遍历字符串(感觉读取只能用前序来读),遇到’#'返回NULL,其余直接创建结点插入,中序遍历输出即可

#include <stdio.h>
 typedef struct BinaryTreeNode{
    char data;
    struct BinaryTreeNode*left;
    struct BinaryTreeNode*right;
}BTNode;
BTNode*BuyNode(char x)
{
    BTNode*NewNode=(BTNode*)malloc(sizeof(BTNode));
    NewNode->data=x;
    NewNode->left=NewNode->right=NULL;
    return NewNode;
}
BTNode* PreoderInsert(char*arr,int*pi)
{
    if(arr[*pi]=='#')
    {
    (*pi)++;
    return NULL;
    }
    BTNode*root=BuyNode(arr[(*pi)++]);
    root->left=PreoderInsert(arr,pi);
    root->right=PreoderInsert(arr,pi);
    return root;
}
void InOder(BTNode*root)
{
    if(root==NULL)
    return;
    InOder(root->left);
    printf("%c ",root->data);
    InOder(root->right);
}
int main() {
    char arr[100];
    scanf("%s",arr);
    int i=0;
    BTNode*root=PreoderInsert(arr,&i);
    InOder(root);
    return 0;
}

8.TopK问题

TOP-K问题:即求数据结合中前K个最⼤的元素或者最⼩的元素,⼀般情况下数据量都⽐较⼤。
⽐如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。
对于Top-K问题,能想到的最简单直接的⽅式就是排序,但是:如果数据量⾮常⼤,排序就不太可取了(可能数据都不能⼀下⼦全部加载到内存中)。最佳的⽅式就是⽤堆来解决,

基本思路如下:
1)⽤数据集合中前K个元素来建堆
前k个最⼤的元素,则建⼩堆
前k个最⼩的元素,则建⼤堆
2)⽤剩余的N-K个元素依次与堆顶元素来⽐较,不满⾜则替换堆顶元素将剩余N-K个元素依次与堆顶元素⽐完之后,堆中剩余的K个元素就是所求的前K个最⼩或者最⼤的元素

设计程序

进行文件操作以写的形式打开,使用rand函数随机生成十万个数据,将前K个数据建堆,遍历剩余的数据与堆顶比较,若是大于则交换并进行向下调整,注意得到的堆是K个最大的元素或者最小的元素,不是排序好的数组。

编写代码

void CreateNDate()
{
	// 造数据
	int n = 100000;
	srand((unsigned)time(NULL));
	FILE* fin = fopen("data.txt", "w");
	if (fin == NULL)
	{
		perror("fopen error");
		return;
	}
	for (int i = 0; i < n; ++i)
	{
		int x = rand();
		fprintf(fin, "%d\n", x);
	}
	fclose(fin);
}

void TOPk()
{
	int k = 0;
	printf("请输入k:");
	scanf("%d", &k);
	FILE* fout = fopen("data.txt", "r");
	if (fout == NULL)
	{
		perror("fopen fail!");
		exit(1);
	}
	int* minHeap = (int*)malloc(k * sizeof(int));
	if (minHeap == NULL)
	{
		perror("malloc fail!");
		exit(2);
	}

	//从文件中读取前K个数据
	for (int i = 0; i < k; i++)
	{
		fscanf(fout, "%d", &minHeap[i]);
	}

	//建堆---小堆
	for (int i = (k - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDown(minHeap, i, k);
	}

	int x = 0;
	while (fscanf(fout, "%d", &x) != EOF)
	{
		//读取到的数据跟堆顶的数据进行比较
		//比堆顶值大,交换入堆
		if (x > minHeap[0])
		{
			minHeap[0] = x;
			AdjustDown(minHeap, 0, k);
		}
	}

	for (int i = 0; i < k; i++)
	{
		printf("%d ", minHeap[i]);
	}

	fclose(fout);
}

int main()
{
CreateNDate();
TOPk();
return 0;
}

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

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

相关文章

本地部署 faster-whisper

本地部署 faster-whisper 1. 创建虚拟环境2. 安装依赖模块3. 创建 Web UI4. 启动 Web UI5. 访问 Web UI 1. 创建虚拟环境 conda create -n faster-whisper python3.11 -y conda activate faster-whisper2. 安装依赖模块 pip install torch2.2.2 torchvision0.17.2 torchaudio…

快讯 | OpenAI迎挑战:开发者转向Sonnet和Llama 405B,GPT-5亟待发布

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…

Golang | Leetcode Golang题解之第312题戳气球

题目&#xff1a; 题解&#xff1a; func maxCoins(nums []int) int {n : len(nums)rec : make([][]int, n 2)for i : 0; i < n 2; i {rec[i] make([]int, n 2)}val : make([]int, n 2)val[0], val[n1] 1, 1for i : 1; i < n; i {val[i] nums[i-1]}for i : n - 1…

网络商城系统/在线购物商城系统/电子商城系统/商品销售系统

获取源码联系方式请查看文章结尾&#x1f345; 摘 要 本毕业设计的内容是设计并且实现一个基于SSM框架的网络商城系统。它是在Windows下&#xff0c;JSP技术&#xff0c;以MYSQL为数据库开发平台&#xff0c;Tomcat网络信息服务作为应用服务器。网络商城系统的功能已基本实现…

pdf转word在线转换免费软件有没有?安利10款pdf转换器,亲测实用!

pdf和 word是两种广泛使用的文件格式&#xff0c;主要用于分享和存储文档。pdf文件能够保留文档的格式和布局。因此&#xff0c;与word文档相比&#xff0c;pdf更适合用于共享和打印。而word文件则易于编辑&#xff0c;使用也比pdf更加普遍。你可以方便地对文本进行修改、添加或…

花排口径的含义

第一种&#xff1a;固定花排模式 第二种&#xff1a;滚动花排模式 实际使用中&#xff0c;可以根据使用用途&#xff0c;选用不同的口径。

【趣味实验】当狼人杀遇上AI:一场颠覆认知的反向图灵测试

「你看&#xff0c;人类一败涂地了」 这是一次「反向图灵测试」&#xff0c;几个全球最先进的大模型坐在一起&#xff0c;坐着火车唱着歌&#xff0c;但其中混进了人类&#xff1a; 而 AI 的任务&#xff0c;是把这个人类揪出来。 最近&#xff0c;一位昵称「Tore Knabe」的网…

新手学习Gazebo+ros仿真控制小车-----易错和自己理解

赵虚左老师讲的很详细&#xff0c;这里只是理一下思路&#xff0c;说下突然出现“新”概念之间的关系。 urdf文件:里面是配置模型的&#xff0c;既有模型的位置、尺寸、颜色&#xff0c;也包含复杂的物理模型信息比如&#xff1a;转动惯量&#xff0c;碰撞box大小等等&#xff…

internlm开源体系

开源体系核心思想 3. nlp的大海捞针实验 当给模型提供一个非常长的背景知识时&#xff0c;模型是否能够完美的定位超长背景知识中任何位置的任何信息 5. minerU可以解析pdf文档为文本 6. 部署 7. 智能体 三种主流的智能体构建方案

国内外最顶级的五款项目管理软件(推荐)

在项目管理中&#xff0c;项目管理软件已成为企业高效运作不可或缺的工具。无论是国内还是国外&#xff0c;市场上都涌现出众多优秀的项目管理软件&#xff0c;它们以各自独特的功能和优势&#xff0c;助力企业实现项目目标&#xff0c;提升团队协作效率。 1、进度猫 Jinduma…

微信失效图片怎么恢复?iPhone用户请收藏这4个策略!

微信在我们的工作和生活中扮演着重要的角色。但有时候我们也会遇到一些小小的困扰&#xff0c;比如微信失效图片怎么恢复。在这篇文章中&#xff0c;小编将为你分享4个实用的策略&#xff0c;帮助你轻松解决这个问题。所以&#xff0c;如果你正在为微信失效图片而烦恼&#xff…

闪耀STIF2023国际科创节,望繁信科技荣获年度行业创新典范奖

2023年12月15日&#xff0c;望繁信科技在STIF2023第四届国际科创节暨DSC2023国际数字服务大会&#xff08;数服会&#xff09;活动评选中&#xff0c;斩获“2023年度行业创新典范”大奖。 作为科技创新与数字化服务领域最具影响力的年度盛会之一&#xff0c;STIF2023国际科创节…

Python对腾讯课程视频链接自动化抓取

近期看到腾讯课堂停服的通知&#xff0c;心痛之余&#xff0c;想到啊&#xff0c;我还有很多课程没看完&#xff0c;就剩下两个月的事件&#xff0c;我也来不及看完了。怎么办&#xff1f; 索性&#xff0c;我研究下&#xff0c;怎么把视频保存下来。 接下来请听我分析。 所…

U盘格式化了怎么恢复数据?教你U盘恢复妙招

U盘作为便携式存储设备&#xff0c;在我们的日常生活和工作中发挥着重要作用。然而&#xff0c;有时由于操作失误或其他原因&#xff0c;我们可能会格式化U盘&#xff0c;从而导致数据丢失。当遭遇这种情况时&#xff0c;很多人会感到焦虑和困惑。不过&#xff0c;幸运的是&…

DeEcoStudio注释改变颜色

第一步&#xff1a;点击文件——>设置 第二步&#xff1a;编辑器——>配色方案 第三步&#xff1a;找到javaScript——>找到Comment——>找到颜色 第四步&#xff1a;颜色

自定义记录日志的注解

自定义记录日志的注解 建日志表实现代码定义注解与表对应的实体类Mapper 和 Service实现自定义注解 使用注解 建日志表 CREATE TABLE system_log (id bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 主键,method_name varchar(255) COLLATE utf8mb4_general_ci NOT NULL CO…

该买 USB 集线器还是 USB 服务器?一文搞懂!

一、引言 当我们遇到USB 设备与电脑的连接问题时&#xff0c;会看到市面上有 USB 集线器和 USB 服务器两种看起来差不多的产品&#xff0c;搞不清楚它们的区别。 接下来给大家详细一下这两种设备&#xff0c;看看它们分别适合什么情况&#xff0c;帮助你做出明智的选择。 二、…

【Material-UI】Autocomplete 组件的局限性(Limitations)详解

文章目录 一、自动完成/自动填充1. 浏览器自动完成的影响2. 自动填充建议 二、iOS VoiceOver三、自定义 ListboxComponent示例代码 四、总结 Material-UI 的 Autocomplete 组件为开发者提供了便捷的自动补全功能&#xff0c;但在实际使用中也有一些需要注意的局限性。本文将详细…

线程 【Linux】

文章目录 线程页表POSIX线程库pthread_create线程等待pthread_join 线程终止pthread_cancelpthread_self 分离线程 线程ID&&进程地址空间布局 线程 在一个程序里的一个执行路线就叫做线程&#xff08;thread&#xff09;。更准确的定义是&#xff1a;线程是“一个进程…

聊聊ChatGLM-6B医疗数据微调

前言 参考了多个医疗大模型&#xff0c;如扁鹊、灵心等&#xff0c;重新思考了下微调的方案以及数据集的格式&#xff1b;基于ChatGLM/其它LLM整合多种微调方法的非官方实现的框架&#xff0c;审视其数据集格式&#xff0c;以及调试效果&#xff0c;进行微调。 最终基于liucon…