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

目录

一.栈

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;
}
相关推荐
devnullcoffee2 小时前
2026年Amazon Listing优化完全指南:COSMO算法与Rufus AI技术解析
人工智能·python·算法·亚马逊运营·amazon listing·cosmo算法·rufus ai技术
Kratzdisteln2 小时前
【1902】优化后的三路径学习系统
android·学习
苦藤新鸡2 小时前
19.旋转输出矩阵
c++·算法·leetcode·力扣
zsffuture2 小时前
RKNN 8位量化全解析:算法差异与粒度选择实战指南
算法
玄冥剑尊2 小时前
贪心算法深化 II
算法·贪心算法
Pluchon2 小时前
硅基计划4.0 算法 动态规划入门
java·数据结构·算法·动态规划
玄冥剑尊2 小时前
贪心算法深化 III
算法·贪心算法
txinyu的博客2 小时前
list 三个经典版本
数据结构·list
仰泳之鹅2 小时前
【PID学习】多环PID
学习·pid