[Data_Structure notes]链栈的创建及相关操作

链栈实现与操作解析
本文深入探讨了链栈的数据结构及其创建与操作方法,包括Push、Pop等关键函数的实现细节,通过C语言代码示例,解析了链栈的工作原理。

[Data_Structure notes]链栈的创建及相关操作

本篇主要记录学习数据结构的一些笔记,以及一些个人思考。
参考书是《数据结构与算法分析(c语言描述)》(机械工业出版社)

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

typedef int Elementtype;
typedef struct Node
{
    Elementtype data;
    struct Node* next;
}Stack;

typedef struct Node* Ptrstack;

int isEmpty(Stack* s);
void Push(Elementtype x,Stack* s);
void Pop(Stack* s);
Stack* CreateStack(void);

int main(void)
{
    Stack* s;
    s=CreateStack();
    Push(2,s);
    Push(3,s);
    Pop(s);
    printf("%d",s->next->data);
    system("pause");
    return 0;
}

/* Routine to create an empty stack */
Stack* CreateStack(void)
{
    Ptrstack p;
    p =(Stack*)malloc(sizeof(Stack));
    if(p != NULL)
    {
       p->next = NULL;
    }
    return p;
}

/* Routine to push an element in the stack */
void Push(Elementtype x,Stack* s)
{
    Ptrstack Tmp;
    Tmp = (Stack*)malloc(sizeof(Stack));
    if(Tmp == NULL) 
        printf("out of space");
    else{
        Tmp->data = x;
        Tmp->next = s->next;
        s->next = Tmp;
    }
}

/* Routine to pop an element in the stack */
void Pop(Stack* s)
{
    Ptrstack FirstCell;
    if(isEmpty(s))
        printf("s is empty");
    else{
        FirstCell = s->next;
        s->next = s->next->next;
        free(FirstCell);
    }
}

int isEmpty(Stack* s)
{
    return s->next == NULL;
}








该书上创建链栈的方法较为独特,与大多数不同(很多都是创建两个结构体,一个用来创建链栈,另一个用来维护链栈,较为容易理解)。个人有两个比较疑惑的地方,一个是MakeEmpty函数的创建,还有一个是Pop的操作也不是特别理解。后来想了一番,把自己的一些个人理解记在这里。

在这里插入图片描述
(不好意思,随手乱画的),每一次新加进来的元素都放在链表的头节点后面,而每一次pop的也是头节点后面的那个元素。至于MakeEmpty函数,应该是为了只保留一个空的头节点,什么也不干,也不保存数据,就是一个头节点。

void TIM16_IRQHandler(void) { TIM_ClearITPendingBit(TIM16, TIM_IT_Update); if(Timecounter) Timecounter--; //LEDXToggle(1); //if(Read_Receive_Flage_Fun()==1) { if((GPIOA->IDR&GPIO_Pin_10)==0) { IR_Receive_Structure.IR_Receive_Low_Counts++; //计数 if(IR_Receive_Structure.IR_Receive_Step_Counts==1) { if(IR_Receive_Structure.IR_Receive_High_Counts>20&&IR_Receive_Structure.IR_Receive_High_Counts<70) IR_Receive_Structure.IR_Receive_Step_Counts=3; //Usart_Send_Data_Fun("高电平:",IR_Receive_Structure.IR_Receive_High_Counts); } else if(IR_Receive_Structure.IR_Receive_Step_Counts==3) { if(IR_Receive_Structure.IR_Receive_High_Low_Flage==1) { IR_Receive_Structure.IR_Receive_High_Low_Flage=0; level_time=IR_Receive_Structure.IR_Receive_Pack_Counts/16%2; if(level_time==0) { IR_Receive_Structure.IR_Re_Data1>>=1; if(IR_Receive_Structure.IR_Receive_High_Counts>9) { IR_Receive_Structure.IR_Re_Data1|=0x8000; //Usart_Send_Data_Fun("1",1); } } else if(level_time==1) { IR_Receive_Structure.IR_Re_Data2>>=1; if(IR_Receive_Structure.IR_Receive_High_Counts>9) { IR_Receive_Structure.IR_Re_Data2|=0x8000; //Usart_Send_Data_Fun("2",2); } } IR_Receive_Structure.IR_Receive_Pack_Counts++; //Usart_Send_Data_Fun("读取数据",IR_Receive_Structure.IR_Receive_Pack_Counts); if(IR_Receive_Structure.IR_Receive_Pack_Counts%16==0) { IR_Receive_Structure.IR_RE_Data_Level++; IR_Receive_Structure.IR_Receive_Signal_Flage=1; //Usart_Send_Data_Fun("录用",0); } if(IR_Receive_Structure.IR_Receive_Pack_Counts>=66) { IR_Receive_Structure.IR_Receive_Signal_Flage=1; IR_Receive_Structure.IR_RE_Data_Level++; } } } IR_Receive_Structure.IR_Receive_High_Counts=0; } else if(GPIOA->IDR&GPIO_Pin_10) //检测高电平 { IR_Receive_Structure.IR_Receive_High_Counts++; //计数 if(IR_Receive_Structure.IR_Receive_Low_Counts>70&&IR_Receive_Structure.IR_Receive_Low_Counts<120) //9ms低电平引导码 { IR_Receive_Structure.IR_Receive_Step_Counts=1; IR_Receive_Structure.IR_Receive_Frame_Counts=0; //IR_Receive_Structure.IR_Re_Data2=0; //IR_Receive_Structure.IR_Re_Data1=0; IR_Receive_Structure.IR_Receive_Pack_Counts=0; IR_Receive_Structure.IR_Receive_High_Low_Flage=0; IR_Receive_Structure.IR_RE_Data_Level=0; IR_Receive_Structure.IR_Receive_Low_Counts=0; //Usart_Send_Data_Fun("引导码",IR_Receive_Structure.IR_Receive_Low_Counts); //Usart_Send_Data_Fun("zhongqian:",IR_Receive_Structure.IR_Receive_Low_Counts); } if(IR_Receive_Structure.IR_Receive_Step_Counts==3) { if(IR_Receive_Structure.IR_Receive_Low_Counts>=2&&IR_Receive_Structure.IR_Receive_Low_Counts<9) { IR_Receive_Structure.IR_Receive_High_Low_Flage=1; } else { IR_Receive_Structure.IR_Receive_High_Low_Flage=0; if(IR_Receive_Structure.IR_Receive_Low_Counts>15&&IR_Receive_Structure.IR_Receive_Low_Counts<30) { IR_Receive_Structure.IR_Receive_Frame_Counts++; IR_Receive_Structure.IR_Receive_Step_Counts=3; IR_Receive_Structure.IR_Receive_Pack_Counts=0; IR_Receive_Structure.IR_Receive_Signal_Flage=0; //Usart_Send_Data_Fun("结束",0); //IR_Receive_Structure.IR_RE_Data_Level=0; //Usart_Send_Data_Fun("Low=:",IR_Receive_Structure.IR_Receive_Low_Counts); } else if(IR_Receive_Structure.IR_Receive_Low_Counts>35&&IR_Receive_Structure.IR_Receive_Low_Counts<70) { IR_Receive_Structure.IR_Receive_Step_Counts=0; //IR_Receive_Structure.IR_Receive_High_Low_Flage=0; IR_Receive_Structure.IR_Receive_Pack_Counts=0; //IR_Receive_Structure.IR_Receive_Signal_Flage=0; IR_Receive_Structure.IR_Receive_Signal_Flage=1; //IR_Receive_Structure.IR_Receive_Sure_Flage=1; //检测到回答 IR_Receive_Structure.IR_Receive_Frame_Counts=0; IR_Receive_Structure.IR_RE_Data_Level=0; //Usart_Send_Data_Fun("结尾",0); } } } //if(IR_Receive_Structure.IR_Receive_Low_Counts) //Usart_Send_Data_Fun("低电平:",IR_Receive_Structure.IR_Receive_Low_Counts); IR_Receive_Structure.IR_Receive_Low_Counts=0; } } TIM_ClearITPendingBit(TIM16, TIM_IT_Update); }STM32F030标准库中断很难检测到低电平,中断时间正常为100us
最新发布
08-06
这段代码是一个STM32F030的定时器中断服务函数,主要用于红外信号的解码。以下是对代码的分析和改进建议: 1. **问题分析**: - 代码试图通过检测GPIOA Pin10的高低电平变化来解码红外信号,但存在电平检测不稳定的问题。 - 中断间隔为100us,但红外信号的解码通常需要更精确的时序控制。 2. **主要问题**: - 电平检测使用`GPIOA->IDR & GPIO_Pin_10`直接读取,可能受中断延迟影响。 - 缺少对电平变化时间的精确测量。 - 中断处理逻辑复杂,可能导致处理延迟。 3. **改进建议**: - 使用输入捕获功能代替软件检测电平变化。 - 简化中断处理逻辑,将复杂解码逻辑移到主循环。 - 增加对信号边沿的检测。 4. **改进后的代码框架**: ```c void TIM16_IRQHandler(void) { static uint32_t lastCapture = 0; uint32_t currentCapture = 0; uint32_t pulseWidth = 0; if(TIM_GetITStatus(TIM16, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM16, TIM_IT_Update); if(Timecounter) Timecounter--; } if(TIM_GetITStatus(TIM16, TIM_IT_CC1) != RESET) // 假设使用通道1的输入捕获 { TIM_ClearITPendingBit(TIM16, TIM_IT_CC1); currentCapture = TIM_GetCapture1(TIM16); pulseWidth = (currentCapture >= lastCapture) ? (currentCapture - lastCapture) : (0xFFFF - lastCapture + currentCapture); lastCapture = currentCapture; // 根据脉冲宽度处理红外信号 if(pulseWidth > 70 && pulseWidth < 120) // 引导码检测 { IR_Receive_Structure.IR_Receive_Step_Counts = 1; // 重置其他状态变量... } else if(IR_Receive_Structure.IR_Receive_Step_Counts == 1) { // 处理数据位... } } } ``` 5. **配置建议**: - 配置TIM16的通道1为输入捕获模式,检测上升沿和下降沿。 - 设置合适的预分频器和自动重装载值以获得精确的时间测量。 - 在主函数中初始化相关GPIO为复用功能模式。 6. **注意事项**: - 红外解码通常需要处理38kHz载波信号,可能需要额外的滤波处理。 - 不同红外协议(NEC、RC5等)的时序要求不同,需要根据具体协议调整检测阈值。 - 考虑使用硬件PWM输入捕获功能提高精度。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值