【从零开始的嵌入式生活】数据结构4——栈与队列(1)

简介: 【从零开始的嵌入式生活】数据结构4——栈与队列(1)

前言

这周因为不能出去就尽量把数据结构更完,每天一篇文章发布,请大家监督我,如果我没法请@我催更0.0

三连即可提高学习效率0.0


🧑🏻作者简介:一个学嵌入式的年轻人

✨联系方式:2201891280(QQ)

📔源码地址:https://gitee.com/xingleigao/study_qianrushi

⏳全文大约阅读时间: 120min


文章目录

前言

顺序栈

创建

入栈

出栈

链式栈

队列

顺序队列

链式队列

相关操作

栈和队列的应用

解决代码

写在最后

栈是限制在一端进行插入操作和删除操作的线性表(俗称堆栈)。

相关的术语:


允许进行操作的一端成为栈顶

另一固定端成为栈底

当栈中没有元素时成为空栈

特点:后进先出


顺序栈

他是顺序表的一种,具有顺序表永阳的存储结构,由数组定义,配合用数组下标表示的栈顶指针top(相对指针)完成各种操作。

定义方式如下:


typedef int data_t; //定义栈中数据元素的数据类型
typedef struct{
  data_t *data; //用指针指向栈的存储空间
  int maxlen; //当前栈的最大元素大小
  int top;  //只是栈顶元素位置
}sqstack;

创建


示例代码:


sqstack * stack_create(int len){
       sqstack * s;
       if ((s = (sqstack *)malloc(sizeof(sqstack)))== NULL){
               printf("malloc sqstack failed\n");
               return NULL;
       }
       if((s->data = (data_t *)malloc(sizeof(data_t) * len))==NULL){
               printf("malloc data failed\n");
               free(s);
               return NULL;
       }
       memset(s->data, 0 , len * sizeof(data_t));
       s->maxlen = len;
       s->top = -1;
       return s;
}


入栈

示例代码:


int stack_push(sqstack * s, data_t value){
       if(s == NULL){
               puts("stack is null");
               return -1;
       }
        if(s->top == s->maxlen - 1){  //判断是否为空
                puts("stack is full");
                return -1;
        }
       s->top++;
       s->data[s->top] = value;
       return 0;
}


出栈


示例代码:


data_t stack_pop(sqstack * s){
       s->top--;
       return (s->data[s->top+1]);
}


其他的操作相对比较简单,建议直接看我gitee上的代码。


链式栈

插入操作和删除操作均在链表头部进行,链表尾部就是栈底,栈顶指针就是头指针。

数据类型定义:


typedef int data_t;
typedef struct node_t{
  data_t data;
  struct node_t *next;
}linkstack_t;


这部分比较简单就直接给相关实现的源码了:


linkstack stack_create(){
        linkstack s;
        s = (linkstack)malloc(sizeof(listnode));
        if(s == NULL){
                puts("malloc failed");
                return NULL;
        }
        s->data = 0;
        s->next = NULL;
        return s;
}
int stack_push(linkstack s, data_t value){
        linkstack p;
        if(s == NULL){
                puts("s is null");
                return -1;
        }
        p = (linkstack)malloc(sizeof(listnode));
        if(p == NULL){
                puts("malloc failed");
                return -1;
        }
        p->data = value;
        //p->next = NULL;
        p->next = s->next;
        s->next = p;
        return 0;
}
data_t stack_pop(linkstack s){
        linkstack p;
        p = s->next;
        s->next = p->next;
        data_t t = p->data;
        free(p);
        p = NULL;
        return t;
}
int stack_empty(linkstack s){
        if(s == NULL){
                puts("s is null");
                return -1;
        }
        return (s->next == NULL ? 1 : 0);
}
data_t stack_top(linkstack s){
        return (s->next->data);
}
linkstack stack_free(linkstack s){
        linkstack p;
        if(s == NULL){
                puts("s is null");
                return NULL;
        }
        while(s != NULL){
                p = s;
                s = s->next;
                printf("free:%d\n", p->data);
                free(p);
        }
        return NULL;
}

队列

队列是限制在两端进行插入操作和删除操作的线性表


允许进行存入操作的一端称为队尾

允许进行删除操作的一端称为队头

当线性表中没有元素时,成为空队

特点:先入先出(FIFO)


队列的操作


创建队列:CreateQueue()

清空队列:ClearQueue(Q)

判断队列空:EmptyQueue(Q)

判断队列满:FullQueue(Q)

入队:EnQueue(Q,x)

出队:DeQueue(Q)

顺序队列

顺序队列的数据结构


typedef int datatype;
#define N 128
typedef struct{
       datatype data[];
       int front;
       int rear;
}


因为之前相关操作都是差不多的,需要注意的只有是循环队列,所以判断条件不太一样,这里相关操作我也直接给代码了:


sequeue *queue_create(){
        sequeue *sq;
        if((sq = (sequeue *)malloc(sizeof(sequeue))) == NULL){
                printf("malloc failed\n");
                return NULL;
        }
        memset(sq->data,0,sizeof(sq->data));
        sq->front = sq->rear = 0;
        return sq;
}
int enqueue(sequeue *sq, datatype x){
        if(sq == NULL){
                printf("sq is null\n");
                return -1;
        }
        if ((sq->rear + 1) % N == sq->front){
                printf("sequeue is full\n");
                return -1;
        }
        sq->data[sq->rear] = x;
        sq->rear = (sq->rear + 1) % N;
        return 0;
}
datatype dequeue(sequeue *sq){
        if(sq == NULL){
                printf("sq is null\n");
                return -1;
        }
        datatype ret;
        ret = sq->data[sq->front];
        sq->front = (sq->front + 1) % N;
        return ret;
}
int queue_empty(sequeue *sq){
        if(sq == NULL){
                printf("sq is null\n");
                return -1;
        }
        return (sq->front == sq->rear ? 1 : 0);
}
int queue_full(sequeue *sq){
        if(sq == NULL){
                printf("sq is null\n");
                return -1;
        }
        if ((sq->rear + 1) % N == sq->front){
                return -1;
        }
        return 0;
}
int queue_clear(sequeue *sq){
        if(sq == NULL){
                printf("sq is null\n");
                return -1;
        }
        sq->front = sq->rear = 0;
        return 0;
}
sequeue * queue_free(sequeue *sq){
        if(sq == NULL){
                printf("sq is null\n");
                return NULL;
        }
        free(sq);
        sq = NULL;
        return sq;
}


一般队列的使用不会声明这么多的结构体啥的,一般都是直接使用一个数组来当作队列使用。出队入队都是一行代码。可以想想怎么写,有时间写个demo。



相关文章
|
22小时前
|
前端开发 JavaScript 算法
JavaScript 中实现常见数据结构:栈、队列与树
JavaScript 中实现常见数据结构:栈、队列与树
|
2天前
|
存储 编译器 C语言
数据结构——顺序队列与链式队列的实现-2
数据结构——顺序队列与链式队列的实现
数据结构——顺序队列与链式队列的实现-2
|
2天前
|
存储 C语言
数据结构——顺序队列与链式队列的实现-1
数据结构——顺序队列与链式队列的实现
数据结构——顺序队列与链式队列的实现-1
|
2天前
|
存储 NoSQL C语言
数据结构——顺序栈与链式栈的实现-2
数据结构——顺序栈与链式栈的实现
数据结构——顺序栈与链式栈的实现-2
|
2天前
|
存储 C语言
数据结构——顺序栈与链式栈的实现-1
数据结构——顺序栈与链式栈的实现
数据结构——顺序栈与链式栈的实现-1
|
2天前
栈的基本应用
栈的基本应用
12 3
|
2天前
栈与队列理解
栈与队列理解
13 1
|
2天前
|
存储 算法
数据结构与算法 栈与队列
数据结构与算法 栈与队列
12 0
数据结构与算法 栈与队列
|
2天前
|
C++
数据结构(顺序队列 循环队列
数据结构(顺序队列 循环队列
10 0
|
2天前
|
C++
数据结构(共享栈
数据结构(共享栈
8 0