嵌入式学习数据结构(三)栈 链式 循环队列

目录

一.栈

1.系统栈

2.顺序表(数组)---》顺序栈

3.链式栈:

头文件

创建链表

入栈(压栈)

出栈(弹栈)

获取栈顶元素

遍历

销毁链式栈

二.队列

1.顺序队列

2.链式队列

头文件

创建队列

入队

出队

获取队头元素

遍历

销毁队列

主函数

3.循环队列

头文件

创建队列

判空

判满

入队

出队

遍历

获取队头元素

销毁队列

主函数


一.栈

1.系统栈

数据结构中的栈:

只允许从一端进行数据的插入和删除的线性存储结构,称之为栈结构

特点:先进后出: FILO

2.顺序表(数组)---》顺序栈

满增栈、满减栈、空增栈、空减栈

满栈、空栈:栈顶所在位置是否存在数据

增栈、减栈:按照栈的生长方向区分

3.链式栈:

头文件

cpp 复制代码
#ifndef __STACK_H__
#define __STACK_H__
 
typedef int Data_type_t;
typedef struct stnode
{
  Data_type_t data;
  struct stnode *pnext;
} STNode_t;
 
typedef struct stack
{
  STNode_t *ptop;
  int clen;
} Stack_t;
 
Stack_t *create_stack();
int is_empty_stack(Stack_t *pstack);
int push_stack(Stack_t *pstack, Data_type_t data);
int pop_stack(Stack_t *pstack, Data_type_t *pdata);
void stack_for_each(Stack_t *pstack);
int get_top_stack(Stack_t *pstack, Data_type_t *pdata);
void destroy_stack(Stack_t **ppstack);
 
#endif

创建链表

cpp 复制代码
Stack_t *create_stack()
{
  Stack_t *pstack = malloc(sizeof(Stack_t));
  if (pstack == NULL)
    {
      printf("malloc error\n");
      return NULL;
    }
  pstack->ptop = NULL;
  pstack->clen = 0;
 
  return pstack;
}

入栈(压栈)

cpp 复制代码
int push_stack(Stack_t *pstack, Data_type_t data)
{
  STNode_t *pnode = malloc(sizeof(STNode_t));
  if (pnode == NULL)
    {
      printf("malloc error\n");
      return -1;
    }
  pnode->pnext = NULL;
  pnode->data = data;
 
  pnode->pnext = pstack->ptop;
  pstack->ptop = pnode;
  pstack->clen++;
}

出栈(弹栈)

cpp 复制代码
int pop_stack(Stack_t *pstack, Data_type_t *pdata)
{
  if (pstack->ptop == NULL)
    {
      return -1;
    }
  else
    {
      STNode_t *ptemp = pstack->ptop;
      pstack->ptop = ptemp->pnext;
      if (pdata != NULL)
        {
          *pdata = ptemp->data;
        }
      free(ptemp);
      pstack->clen--;
      return 0;
    }
}

获取栈顶元素

cpp 复制代码
int get_top_stack(Stack_t *pstack, Data_type_t *pdata)
{
  if (NULL == pstack->ptop)
    {
      return -1;
    }
  if (NULL == pdata)
    {
      return -1;
    }
  *pdata = pstack->ptop->data;
  return 0;
}

遍历

cpp 复制代码
void stack_for_each(Stack_t *pstack)
{
  STNode_t *ptemp = pstack->ptop;
 
  while (ptemp != NULL)
    {
      printf("%d", ptemp->data);
      ptemp = ptemp->pnext;
    }
  printf("\n");
}

销毁链式栈

cpp 复制代码
void destroy_stack(Stack_t **ppstack)
{
  while (!is_empty_stack(*ppstack))
    {
      pop_stack(*ppstack, NULL);
    }
  free(*ppstack);
  *ppstack = NULL;
}

主函数

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"
 
int main(void)
{
  Data_type_t data;
  Stack_t* pstack = create_stack();
  if (NULL == pstack)
    {
      return -1;
    }
  push_stack(pstack, 0);
  push_stack(pstack, 1);
  push_stack(pstack, 2);
  push_stack(pstack, 3);
  push_stack(pstack, 4);
  stack_for_each(pstack);
  int ret = pop_stack(pstack, &data);
  if (ret == 0)
    {
      printf("data = %d\n", data);
    }
  stack_for_each(pstack);
  ret = get_top_stack(pstack, &data);
  if (0 == ret)
    {
      printf("top : %d\n", data);
    }
  destroy_stack(&pstack);
}

二.队列

允许从一端进行数据的插入,另一端进行数据的删除的线性存储结构,称为队列结构。

插入操作:入队操作,插入这端称为队列的队尾。

删除操作:出队操作,删除这端称为队列的队头。

特点:先进先出(FIFO)

应用:数据缓存

1.顺序队列

顺序表---->顺序队列---->假溢出问题---->循环队列

判空:队头,队尾处于同一位置

判满:当队尾+1跟上队头时

循环队列为了区分队空和队满,将少存储一个数据

2.链式队列

头文件

cpp 复制代码
#ifndef __LQUEUE_H__
#define __LQUEUE_H__


typedef int Data_type_t;

typedef struct lqnode
{
    Data_type_t data;
    struct lqnode *pnext;
}LQNode_t;


typedef struct lqueue
{
    LQNode_t *phead;
    LQNode_t *ptail;
    int clen;
}LQueue_t;


extern LQueue_t *create_link_queue();
extern void link_queue_for_each(LQueue_t *plq);
extern int push_link_queue(LQueue_t *plq, Data_type_t data);
extern int is_empty_link_queue(LQueue_t *plq);
extern int pop_link_queue(LQueue_t *plq, Data_type_t *pdata);
extern void destroy_link_queue(LQueue_t **pplq);
extern int get_queue_head(LQueue_t *plq, Data_type_t *pdata);

#endif

创建队列

cpp 复制代码
LQueue_t* create_lqueue()
{
  LQueue_t* plqueue = malloc(sizeof(LQueue_t));
  if (NULL == plqueue)
    {
      printf("malloc error\n");
      return NULL;
    }
  plqueue->phead = NULL;
  plqueue->ptail = NULL;
  plqueue->clen = 0;
  return plqueue;
}

入队

cpp 复制代码
int in_plqueue_tail(LQueue_t* plqueue, Data_type_t data)
{
  LQNode_t* pnode = malloc(sizeof(LQNode_t));
  if (pnode == NULL)
    {
      printf("malloc error\n");
      return -1;
    }
  pnode->pnext = NULL;
  pnode->data = data;
  if (is_empty_plqueue(plqueue))
    {
      plqueue->phead = pnode;
      plqueue->ptail = pnode;
      plqueue->clen++;
    }
  else
    {
      plqueue->ptail->pnext = pnode;
      plqueue->ptail = pnode;
      plqueue->clen++;
    }
  return 0;
}

出队

cpp 复制代码
int out_plqueue_head(LQueue_t* plqueue)
{
  LQNode_t* ptemp = plqueue->phead;
  if (is_empty_plqueue(plqueue))
    {
      return -1;
    }
  if (plqueue->phead == plqueue->ptail)
    {
      free(ptemp);
      plqueue->phead = NULL;
      plqueue->ptail = NULL;
      plqueue->clen--;
    }
  else
    {
      plqueue->phead = ptemp->pnext;
      free(ptemp);
      plqueue->clen--;
    }
}

获取队头元素

cpp 复制代码
int get_top_plqueue(LQueue_t* plqueue, Data_type_t* data)
{
  if (is_empty_plqueue(plqueue))
    {
      return -1;
    }
  *data = plqueue->phead->data;
  return 0;
}

遍历

cpp 复制代码
int plqueue_for_each(LQueue_t* plqueue)
{
  LQNode_t* ptemp = plqueue->phead;
 
  if (is_empty_plqueue(plqueue))
    {
      return -1;
    }
  while (ptemp != NULL)
    {
      printf("%2d", ptemp->data);
      ptemp = ptemp->pnext;
    }
  printf("\n");
}

销毁队列

cpp 复制代码
int destory_plqueue(LQueue_t** pplqueue)
{
  while (!is_empty_plqueue(*pplqueue))
    {
      out_plqueue_head(*pplqueue);
    }
  free(*pplqueue);
  *pplqueue = NULL;
}

主函数

cpp 复制代码
#include <stdio.h>
#include "lqueue.h"
int main(void)
{
  LQueue_t* plqueue = create_lqueue();
  if (plqueue == NULL)
    {
      return -1;
    }
  in_plqueue_tail(plqueue, 0);
  in_plqueue_tail(plqueue, 1);
  in_plqueue_tail(plqueue, 2);
  in_plqueue_tail(plqueue, 3);
  in_plqueue_tail(plqueue, 4);
  out_plqueue_head(plqueue);
  plqueue_for_each(plqueue);
  Data_type_t data;
  int ret = get_top_plqueue(plqueue, &data);
  if (ret == 0)
    {
      printf("top = %d\n", data);
    }
  destory_plqueue(&plqueue);
}

3.循环队列

头文件

cpp 复制代码
#ifndef __SEQQUE_H_
#define __SEQQUE_H_
 
#define SEQQUE_MAX_LEN 10
 
typedef int Data_type_t;
 
typedef struct seqque
{
  Data_type_t *pbase;
  int head;
  int tail;
} Seqque_t;
 
extern Seqque_t *create_seqque();
extern int is_full_seqque(Seqque_t *psq);
extern int is_empty_seqque(Seqque_t *psq);
extern int push_seqque(Seqque_t *psq, Data_type_t data);
extern void seqque_for_each(Seqque_t *psq);
extern int out_seqque(Seqque_t *psq, Data_type_t *data);
extern int get_head_seqque(Seqque_t *psq, Data_type_t *data);
extern void destory_seqque(Seqque_t **psq);
#endif

创建队列

cpp 复制代码
Seqque_t *create_seqque()
{
  Seqque_t *psq = malloc(sizeof(Seqque_t));
  if (NULL == psq)
    {
      printf("malloc error\n");
      return NULL;
    }
  psq->head = 0;
  psq->tail = 0;
  psq->pbase = malloc(sizeof(Data_type_t) * SEQQUE_MAX_LEN);
  if (NULL == psq->pbase)
    {
      printf("malloc error\n");
      return NULL;
    }
 
  return psq;
}

判空

cpp 复制代码
int is_empty_seqque(Seqque_t *psq)
{
  if (psq->head == psq->tail)
    {
      return 1;
    }
  return 0;
}

判满

cpp 复制代码
int is_full_seqque(Seqque_t *psq)
{
  if ((psq->tail + 1) % SEQQUE_MAX_LEN == psq->head)
    {
      return 1;
    }
  return 0;
}

入队

cpp 复制代码
int push_seqque(Seqque_t *psq, Data_type_t data)
{
  if (is_full_seqque(psq))
    {
      printf("seqque is full\n");
      return -1;
    }
 
  psq->pbase[psq->tail] = data;
  psq->tail = (psq->tail + 1) % SEQQUE_MAX_LEN;
 
  return 0;
}

出队

cpp 复制代码
int out_seqque(Seqque_t *psq, Data_type_t *data)
{
  if (is_empty_seqque(psq) || NULL == data)
    {
      printf("seqque is empty\n");
      return -1;
    }
 
  *data = psq->pbase[psq->head];
  psq->head = (psq->head + 1) % SEQQUE_MAX_LEN;
  return 0;
}

遍历

cpp 复制代码
void seqque_for_each(Seqque_t *psq)
{
  for (int i = psq->head; i != psq->tail; i = (i + 1) % SEQQUE_MAX_LEN)
    {
      printf("%d ", psq->pbase[i]);
    }
  printf("\n");
}

获取队头元素

cpp 复制代码
int get_head_seqque(Seqque_t *psq, Data_type_t *data)
{
  if (is_empty_seqque(psq) || NULL == data)
    {
      printf("seqque is empty\n");
      return -1;
    }
 
  *data = psq->pbase[psq->head];
}

销毁队列

cpp 复制代码
void destory_seqque(Seqque_t **psq)
{
  free((*psq)->pbase);
  free(*psq);
  *psq = NULL;
}

主函数

cpp 复制代码
#include <stdio.h>
#include "seqque.h"
 
int main(void)
{
  Seqque_t *psq = create_seqque();
  if (NULL == psq)
    {
      return -1;
    }
 
  for (int i = 0; i < 10; i++)
    {
      push_seqque(psq, i);
    }
  Data_type_t data;
  seqque_for_each(psq);
  out_seqque(psq, &data);
  if (out_seqque(psq, &data) == 0)
    {
      printf("%d\n", data);
    }
  seqque_for_each(psq);
  destory_seqque(&psq);
 
  return 0;
}
相关推荐
UIU11412 分钟前
P16237 [蓝桥杯 2026 省 B] 应急布线
数据结构·c++·算法·蓝桥杯
旖旎夜光15 分钟前
LeetCode 315: 算右侧小于当前元素的个数(归并排序) —— 题解
c++·学习·算法·leetcode·排序算法
像风一样自由202024 分钟前
2.如何用FastAPI把一个Python算法封装成HTTP服务
python·算法·fastapi
D e re k ZH30 分钟前
保序回归:从 PAVA 到可并堆的单调约束优化
c++·算法·数据挖掘·回归·kotlin
青少儿编程课堂31 分钟前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:字典树前缀树与单词检索统计
c++·python·算法·bfs·信息学竞赛
Nuanyt35 分钟前
LeetCode Hot 100 链表专题2 3 题 (Java)
java·笔记·算法·leetcode·链表
海绵宝宝转agent1 小时前
LeetCodehot100题解
java·笔记·学习·算法·leetcode·深度优先
青少儿编程课堂1 小时前
2026蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:堆排序与优先队列解析
c++·python·算法·bfs·信息学竞赛
芒果作者1 小时前
我决定系统学习 Codex,并建立一套自己的知识库
学习
电子科技圈2 小时前
Arm电机控制开发工具哪家强?
arm开发·单片机·嵌入式硬件·设计模式·软件构建