【C/C++数据结构】栈与队列

目录

一、栈

二、队列

三、循环队列


一、栈

特性:

  • 顺序存储,后进先出
  • 优点是可随机访问,尾部增删效率高
  • 缺点是可能会浪费空间,不知道头部增删
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>

#define CAPACITY 3  //默认初识容量
typedef int SData;

typedef struct Stack 
{
    SData* data;
    size_t size;
    size_t capacity;
}Stack;

void Init(Stack* s) 
{
    assert(s);
    s->data = (SData*)malloc(sizeof(SData) * CAPACITY);
    if (s == NULL) 
    {
        perror("init::malloc");
        exit(1);
    }
    s->size = 0;
    s->capacity = CAPACITY;
}

bool Empty(Stack* s) 
{
    assert(s);
    return s->size == 0;
}

void CheckCapacity(Stack* s) 
{
    assert(s);
    if (s->size == s->capacity) {
        SData* tmp = (SData*)realloc(s->data, sizeof(SData) * (s->size + CAPACITY));
        if (tmp == NULL) 
        {
            perror("realloc");
            exit(1);
        }
        s->data = tmp;
        s->capacity += CAPACITY;
    }
}

void Push(Stack* s, SData x) 
{
    assert(s);
    CheckCapacity(s);
    s->data[s->size] = x;
    ++s->size;
}

void Pop(Stack* s) 
{
    assert(s);
    if (!Empty(s)) 
        --s->size;
}

size_t Size(Stack* s) 
{
    assert(s);
    printf("the stack size is %d\n", s->size);
    return s->size;
}

void PrintStack(Stack* s) 
{
    assert(s);
    if (!Empty(s)) 
    {
        int i = 0;
        while (i < s->size) 
        {
            printf("%d ", s->data[i]);
            ++i;
        }
        printf("\n");
    }

}

int main() 
{
    Stack s;
    Init(&s);
    Push(&s, 1);
    Push(&s, 3);
    Push(&s, 2);
    Push(&s, 4);
    Size(&s);
    PrintStack(&s); 
    Pop(&s);
    Pop(&s);
    Pop(&s);
    Pop(&s);
    Pop(&s);
    Size(&s);
    PrintStack(&s);
    return 0;
}

二、队列

特性:

  • 链式存储,先进先出
  • 优点是无空间浪费,头部增删效率高
  • 缺点是不能随机访问,尾部增删效率低
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>

typedef int QData;

typedef struct Queue 
{
    QData data;
    struct Queue* next;
}Queue;

void Init(Queue* q) 
{
    assert(q);
    q->next = (Queue*)malloc(sizeof(Queue));
    q->next->next = NULL;
}

bool Empty(Queue* q) 
{
    assert(q);
    return q->next->next == NULL;
}

void Push(Queue* q, QData x) 
{
    assert(q);
    Queue* node = (Queue*)malloc(sizeof(Queue));
    node->data = x;
    node->next = q->next->next;
    q->next->next = node;
}

void Pop(Queue* q) 
{
    assert(q);
    if (!Empty(q)) 
    {
        Queue* cur = q->next->next;
        q->next->next = cur->next;
        free(cur);
        cur = NULL;
    }
}

size_t Size(Queue* q) 
{
    assert(q);
    size_t size = 0;
    if (!Empty(q)) 
    {
        Queue* cur = q->next->next;
        while (cur) 
        {
            ++size;
            cur = cur->next;
        }
    }
    printf("the list size is %d\n", size);
    return size;
}

void PrintQueue(Queue* q) 
{
    assert(q);
    if (!Empty(q)) 
    {
        Queue* cur = q->next->next;
        printf("%d ", cur->data);
        while (cur->next) 
        {
            printf("-> %d ", cur->next->data);
            cur = cur->next;
        }
        printf("\n");
    }
}

int main() 
{
    Queue q;
    Init(&q);
    Push(&q, 1);
    Push(&q, 3);
    Push(&q, 4);
    Push(&q, 2);
    Size(&q);
    PrintQueue(&q);
    Pop(&q);
    Pop(&q);
    Pop(&q);
    Pop(&q);
    Pop(&q);
    Size(&q);
    PrintQueue(&q);
    return 0;
}

三、循环队列

特性:

  • 顺序存储,先进先出,头删尾增
  • 初始化设定空间容量CAPACITY,数据存储量比空间容量少1(空位区分满和空)
  • head和tail的加减要考虑队列是否存满以及和CAPACITY的关系
  • 判空:return tail == head;
  • 判满:return (tail + 1) % CAPACITY == head;
  • Push:判断非满,tail = (tail + 1)% CAPACITY;
  • Pop: 判断非空,head = (head + 1)% CAPACITY;
  • 优点:空间可重复利用,支持随机访问
  • 缺点:空间有限不可扩容
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>

#define CAPACITY 5     //总容量为5,数据容量为4
typedef int CQData;

typedef struct CirQue 
{
    CQData* data;
    int head;
    int tail;
    int size;
}CirQue;

void Init(CirQue* cq) 
{
    assert(cq);
    cq->data = (CQData*)malloc(sizeof(CQData) * CAPACITY); //多开辟一个空间
    cq->head = cq->tail = cq->size = 0;
}

bool Empty(CirQue* cq) 
{
    assert(cq);
    return cq->head == cq->tail;
}

bool Full(CirQue* cq) 
{
    assert(cq);
    return (cq->tail + 1) % CAPACITY == cq->head;
}

int Size(CirQue* cq) 
{
    assert(cq);
    return (cq->tail + CAPACITY - cq->head) % CAPACITY;
}

void Push(CirQue* cq, CQData x) 
{
    assert(cq);
    if (!Full(cq)) 
    {
        cq->data[cq->tail] = x;
        cq->tail = (cq->tail + 1) % CAPACITY;
    }
}

void Pop(CirQue* cq) 
{
    assert(cq);
    if (!Empty(cq)) 
        cq->head = (cq->head + 1) % CAPACITY;
}

void PrintCirQue(CirQue* cq) 
{
    assert(cq);
    if (!Empty(cq)) 
    {
        int pos = cq->head;
        int size = Size(cq);
        while (size--) 
        {
            printf("%d ", cq->data[pos]);
            pos = (pos + 1) % CAPACITY;
        }
        printf("\n");
    }
}

int main () 
{
    CirQue cq;
    Init(&cq);
    Push(&cq, 1);
    Push(&cq, 3);
    Push(&cq, 5);
    printf("the CirQue size is %d\n", Size(&cq));
    PrintCirQue(&cq);//1 3 5
    Push(&cq, 2);
    Push(&cq, 4);
    Push(&cq, 6);
    printf("the CirQue size is %d\n", Size(&cq));
    PrintCirQue(&cq);//1 3 5 2
    Pop(&cq);
    Pop(&cq);
    Pop(&cq);
    printf("the CirQue size is %d\n", Size(&cq));
    PrintCirQue(&cq);//2
    Push(&cq, 10);
    Push(&cq, 20);
    Push(&cq, 30);
    Push(&cq, 40);
    printf("the CirQue size is %d\n", Size(&cq));
    PrintCirQue(&cq);//2 10 20 30
    Pop(&cq);
    Pop(&cq);
    Pop(&cq);
    Pop(&cq);
    Pop(&cq);
    Pop(&cq);
    printf("the CirQue size is %d\n", Size(&cq));
    PrintCirQue(&cq);
    return 0;
}
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AllinTome

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值