2.7日学习总结

news2025/2/8 19:01:18

深入探究栈、队列与二叉树

一、栈的深度剖析

  1. 进阶特性:除了常规的入栈、出栈操作,栈在处理函数调用、表达式求值等场景时,展现出独特的递归模拟能力。利用栈可以将递归算法转化为非递归形式,有效避免因递归过深导致的栈溢出问题。例如,计算斐波那契数列,递归方式简单直观但效率低且易栈溢出,通过栈模拟递归过程,能精准控制计算流程,提升性能。

  2. 题目(括号匹配)

   题目描述:给定一个只包含括号字符(如 ()、[]、{})的字符串,判断括号是否匹配正确。例如,{[()]} 是匹配的,{[(])} 是不匹配的。

解题思路:使用栈来存储左括号,遍历字符串,遇到左括号则入栈,遇到右括号时,检查栈顶元素是否与之匹配的左括号,若匹配则出栈,否则说明括号不匹配。最后检查栈是否为空,为空则表示所有括号匹配成功。

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

#define MAX_SIZE 100

typedef struct {
    char data[MAX_SIZE];
    int top;
} Stack;

void initStack(Stack *s) {
    s->top = -1;
}

int isEmpty(Stack *s) {
    return s->top == -1;
}

void push(Stack *s, char c) {
    if (s->top == MAX_SIZE - 1) {
        printf("Stack Overflow!\n");
        return;
    }
    s->top++;
    s->data[s->top] = c;
}

char pop(Stack *s) {
    if (isEmpty(s)) {
        printf("Stack Underflow!\n");
        return '\0';
    }
    char c = s->data[s->top];
    s->top--;
    return c;
}

int isMatch(char left, char right) {
    if (left == '(' && right == ')') return 1;
    if (left == '[' && right == ']') return 1;
    if (left == '{' && right == '}') return 1;
    return 0;
}

int bracketMatch(char *str) {
    Stack s;
    initStack(&s);
    for (int i = 0; i < strlen(str); i++) {
        if (str[i] == '(' || str[i] == '[' || str[i] == '{') {
            push(&s, str[i]);
        } else if (str[i] == ')' || str[i] == ']' || str[i] == '}') {
            if (isEmpty(&s) ||!isMatch(pop(&s), str[i])) {
                return 0;
            }
        }
    }
    return isEmpty(&s);
}

int main() {
    char str[MAX_SIZE];
    printf("请输入括号字符串:");
    scanf("%s", str);
    if (bracketMatch(str)) {
        printf("括号匹配成功!\n");
    } else {
        printf("括号匹配失败!\n");
    }
    return 0;
}

二、队列的进阶探索

  1. 优化应用:在多线程编程环境下,队列常用于实现线程间的安全通信。生产者线程将数据放入队列,消费者线程从队列中取出数据处理,通过合理的同步机制(如互斥锁、信号量)确保数据一致性与操作的有序性,避免资源竞争冲突。

  1. 题目示例 - 滑动窗口最大值

题目描述:给定一个整数数组 nums 和一个整数 k,表示滑动窗口的大小,求滑动窗口在数组上滑动时,每个窗口内的最大值。例如,nums = [1,3,-1,-3,5,3,6,7],k = 3,输出应为 [3,3,5,5,6,7]。

解题思路:利用双端队列(一种特殊的队列结构,两端均可进出元素),队列中存储数组元素的下标,保证队列头部始终为当前窗口内的最大值下标。遍历数组,当新元素入队时,将小于新元素的队尾元素依次出队,确保队列单调递减,然后根据窗口移动,判断队头元素是否在窗口内,若不在则出队,最后取队头元素对应的值作为当前窗口最大值。

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

typedef struct Node {
    int index;
    struct Node *next;
} Node;

typedef struct Deque {
    Node *front;
    Node *rear;
} Deque;

void initDeque(Deque *dq) {
    dq->front = dq->rear = NULL;
}

int isEmptyDeque(Deque *dq) {
    return dq->front == NULL;
}

void pushBack(Deque *dq, int index) {
    Node *newNode = (Node *)malloc(sizeof(Node));
    newNode->index = index;
    newNode->next = NULL;
    if (dq->rear == NULL) {
        dq->front = dq->rear = newNode;
    } else {
        dq->rear->next = newNode;
        dq->rear = newNode;
    }
}

void pushFront(Deque *dq, int index) {
    Node *newNode = (Node *)malloc(sizeof(Node));
    newNode->index = index;
    newNode->next = dq->front;
    if (dq->front == NULL) {
        dq->front = dq->rear = newNode;
    } else {
        dq->front = newNode;
    }
}

int popFront(Deque *dq) {
    if (isEmptyDeque(dq)) {
        return -1;
    }
    Node *temp = dq->front;
    int index = temp->index;
    dq->front = dq->front->next;
    if (dq->front == NULL) {
        dq->rear = NULL;
    }
    free(temp);
    return index;
}

int popBack(Deque *dq) {
    if (isEmptyDeque(dq)) {
        return -1;
    }
    Node *prev = NULL;
    Node *curr = dq->front;
    while (curr->next!= NULL) {
        prev = curr;
        curr = curr->next;
    }
    int index = curr->index;
    if (prev == NULL) {
        dq->front = dq->rear = NULL;
    } else {
        prev->next = NULL;
        dq->rear = prev;
    }
    free(curr);
    return index;
}

int getFront(Deque *dq) {
    if (isEmptyDeque(dq)) {
        return -1;
    }
    return dq->front->index;
}

int getBack(Deque *dq) {
    if (isEmptyDeque(dq)) {
        return -1;
    }
    return dq->rear->index;
}

int* maxSlidingWindow(int* nums, int numsSize, int k, int* returnSize) {
    if (numsSize == 0) {
        *returnSize = 0;
        return NULL;
    }
    Deque dq;
    initDeque(&dq);
    int* result = (int*)malloc((numsSize - k + 1) * sizeof(int));
    *returnSize = numsSize - k + 1;
    for (int i = 0; i < k; i++) {
        while (!isEmptyDeque(&dq) && nums[getBack(&dq)] <= nums[i]) {
            popBack(&dq);
        }
        pushBack(&dq, i);
    }
    result[0] = nums[getFront(&dq)];
    for (int i = k; i < numsSize; i++) {
        if (!isEmptyDeque(&dq) && getFront(&dq) <= i - k) {
            popFront(&dq);
        }
        while (!isEmptyDeque(&dq) && nums[getBack(&dq)] <= nums[i]) {
            popBack(&dq);
        }
        pushBack(&dq, i);
        result[i - k + 1] = nums[getFront(&dq)];
    }
    return result;
}

int main() {
    int nums[] = {1,3,-1,-3,5,3,6,7};
    int k = 3;
    int returnSize;
    int* result = maxSlidingWindow(nums, sizeof(nums) / sizeof(nums[0]), k, &returnSize);
    for (int i = 0; i < returnSize; i++) {
        printf("%d ", result[i]);
    }
    printf("\n");
    free(result);
    return 0;
}

三、二叉树的深度挖掘

  1. 高级遍历技巧:在二叉树遍历基础上,衍生出了 Morris 遍历算法,它能在不使用额外栈空间(仅利用原树的空指针)的情况下,实现前序、中序、后序遍历,极大地优化了空间复杂度,对于大规模二叉树处理优势明显。

  1. 题目示例 - 二叉树的最近公共祖先

题目描述:给定一个二叉树,找出两个指定节点 p、q 的最近公共祖先。例如,在下面这棵二叉树中:

  3

 / \

 5 1

/ \ / \

6 2 0 8

  / \

  7 4

若 p = 5,q = 4,则最近公共祖先为 3。

解题思路:可以采用递归方法,从根节点开始遍历,若当前节点为空或等于 p 或 q,则返回当前节点;分别递归左子树和右子树,若左右子树返回值都不为空,则当前节点为最近公共祖先;若只有一个子树返回值不为空,则返回该子树的返回值。

四、总结

通过对栈、队列和二叉树的深入探究,结合实例题目演练,我们解锁了它们更多隐藏的潜能。这些知识不仅丰富了我们的编程技能库,更是在面对复杂算法设计、系统优化等任务时,为我们提供了多样化的解决方案。持续钻研、反复实践,定能让这些数据结构在你的指尖焕发出更强大的创造力,助力你攀登 C 语言编程的更高峰。

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

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

相关文章

Nginx进阶篇 - nginx多进程架构详解

文章目录 1. nginx的应用特点2. nginx多进程架构2.1 nginx多进程模型2.2 master进程的作用2.3 进程控制2.4 worker进程的作用2.5 worker进程处理请求的过程2.6 nginx处理网络事件 1. nginx的应用特点 Nginx是互联网企业使用最为广泛的轻量级高性能Web服务器&#xff0c;其特点是…

【算法专场】分治(下)

目录 前言 归并排序 思想 912. 排序数组 算法思路 算法代码 LCR 170. 交易逆序对的总数 算法思路 算法代码 315. 计算右侧小于当前元素的个数 - 力扣&#xff08;LeetCode&#xff09; 算法思路 算法代码 493. 翻转对 算法思路 算法代码 好久不见~时隔多日&…

OSPF基础(2):数据包详解

OSPF数据包(可抓包) OSPF报文直接封装在IP报文中&#xff0c;协议号89 头部数据包内容&#xff1a; 版本(Version):对于OSPFv2&#xff0c;该字段值恒为2(使用在IPV4中)&#xff1b;对于OSPFv3&#xff0c;该字段值恒为3(使用在IPV6中)。类型(Message Type):该OSPF报文的类型。…

Docker Desktop安装kubernetes时一直在Starting:Kubernetes failed to start

原因&#xff1a;由于墙的问题&#xff0c;导致拉取国外的K8s镜像失败 解决&#xff1a; 下载 k8s-for-docker-desktop 选中自己的kubernetes 版本 下载zip包 PowerShell运行load_images.ps1文件 重启docker kubernetes运行成功

StarSpider 星蛛 爬虫 Java框架 可以实现 lazy爬取 实现 HTML 文件的编译,子标签缓存等操作

StarSpider 星蛛 爬虫 Java框架 开源技术栏 StarSpider 能够实现 针对 HTML XSS SQL 数学表达式等杂乱数据的 爬取 解析 提取 需求&#xff01; 目录 文章目录 StarSpider 星蛛 爬虫 Java框架目录介绍如何获取&#xff1f;maven配置 架构是什么样的&#xff1f;结果对象的类…

【翻译+论文阅读】DeepSeek-R1评测:粉碎GPT-4和Claude 3.5的开源AI革命

目录 一、DeepSeek-R1 势不可挡二、DeepSeek-R1 卓越之处三、DeepSeek-R1 创新设计四、DeepSeek-R1 进化之路1. 强化学习RL代替监督微调学习SFL2. Aha Moment “啊哈”时刻3. 蒸馏版本仅采用SFT4. 未来研究计划 部分内容有拓展&#xff0c;部分内容有删除&#xff0c;与原文会有…

动态规划LeetCode-121.买卖股票的最佳时机1

给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从这笔交易中获取的最大利润。…

#渗透测试#批量漏洞挖掘#微商城系统 goods SQL注入漏洞

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…

import { Component, Vue, Prop, Watch } from ‘vue-property-decorator‘

文章目录 导入部分的解释总结Vue 3 的推荐替代方案总结 你提供的代码片段是使用 vue-property-decorator 库的示例&#xff0c;这是一个第三方库&#xff0c;它提供了 Vue 组件的装饰器&#xff0c;使得编写类风格的 Vue 组件更加方便。以下是对代码中每个部分的详细解释&…

X Window System 架构概述

X Window System 架构概述 1. X Server 与 X Client ​ 这里引入一张维基百科的图&#xff0c;在Linux系统中&#xff0c;若用户需要图形化界面&#xff0c;则可以使用X Window System&#xff0c;其使用**Client-Server**架构&#xff0c;并通过网络传输相关信息。 ​ ​ X…

【ArcGIS Pro 简介1】

ArcGIS Pro 是由 Esri &#xff08;Environmental Systems Research Institute&#xff09;公司开发的下一代桌面地理信息系统&#xff08;GIS&#xff09;软件&#xff0c;是传统 ArcMap 的现代化替代产品。它结合了强大的空间分析能力、直观的用户界面和先进的三维可视化技术…

启明星辰发布MAF大模型应用防火墙产品,提升DeepSeek类企业用户安全

2月7日&#xff0c;启明星辰面向DeepSeek等企业级大模型业务服务者提供的安全防护产品——天清MAF&#xff08;Model Application Firewall&#xff09;大模型应用防火墙产品正式发布。 一个新赛道将被开启…… DeepSeek的低成本引爆赛道规模 随着DeepSeek成为当前最热的现象级…

小米AI眼镜官微上线,将与小米15 Ultra同台亮相,近屿智能用心培育 AI 人才

近日&#xff0c;小米眼镜官微已正式上线&#xff0c;认证主体为小米通讯技术有限公司。据悉&#xff0c;小米AI眼镜已获得入网许可&#xff0c;并计划提前至2月发布&#xff0c;与小米15 Ultra同台亮相。 此前&#xff0c;小米AI眼镜原定于2025年3月至4月发布。早在去年&#…

Mac下使用brew安装go 以及遇到的问题

首先按照网上找到的命令进行安装 brew install go 打开终端输入go version&#xff0c;查看安装的go版本 go version 配置环境变量 查看go的环境变量配置&#xff1a; go env 事实上安装好后的go已经可以使用了。 在home/go下新建src/hello目录&#xff0c;在该目录中新建…

在rtthread中,scons构建时,它是怎么知道是从rtconfig.h找宏定义,而不是从其他头文件找?

在rtthread源码中&#xff0c;每一个bsp芯片板级目录下都有一个 SConstruct scons构建脚本的入口&#xff0c; 在这里把rtthread tools/目录下的所有模块都添加到了系统路径中&#xff1a; 在tools下所有模块中&#xff0c;最重要的是building.py模块&#xff0c;在此脚本里面…

Unity游戏(Assault空对地打击)开发(7) 爆炸效果

效果 准备 首先请手搓一个敌军基地。 然后添加一个火焰特效插件或者自建。 爆炸脚本编写 新建一个脚本命名为Explode。 无需挂载到对象上。 首先是全部代码。 using System.Collections; using System.Collections.Generic; using System.Linq; using TMPro; using UnityEngine…

嵌入式面试题 C/C++常见面试题整理_7

一.什么函数不能声明为虚函数? 常见的不能声明为虚函数的有:普通函数(非成员函数):静态成员函数;内联成员函数;构造函数;友元函数。 1.为什么C不支持普通函数为虚函数?普通函数(非成员函数)只能被overload&#xff0c;不能被override&#xff0c;声明为虚函数也没有什么意思…

excel实用问题:提取文字当中的数字进行运算

0、前言&#xff1a; 这里汇总在使用excel工作过程中遇到的问题&#xff0c;excel使用wps版本&#xff0c;小规模数据我们自己提取数据可行&#xff0c;大规模数据就有些难受了&#xff0c;因此就产生了如下处理办法。 需求&#xff1a;需要把所有文字当中的数字提取出来&…

【prompt实战】AI +OCR技术结合ChatGPT能力项目实践(BOL提单识别提取专家)

本文原创作者:姚瑞南 AI-agent 大模型运营专家,先后任职于美团、猎聘等中大厂AI训练专家和智能运营专家岗;多年人工智能行业智能产品运营及大模型落地经验,拥有AI外呼方向国家专利与PMP项目管理证书。(转载需经授权) 目录 1. 需求背景 2. 目标 3. BOL通用处理逻辑…

昇思打卡营第五期(MindNLP特辑)番外:硅基流动 x 华为云DeepSeek V3 API推理MindTinyRAG

1.前言 前脚&#xff0c;DeepSeek面临的巨头企业官宣加入vs多国政府下场质疑的冰火两重天局势尚未平静&#xff08;DeepSeek在美两重天&#xff1a;五大巨头接入&#xff0c;政府诚惶诚恐&#xff09;&#xff1b;后脚&#xff0c;OpenAI被逼急&#xff0c;凌晨亮出全新推理…