Quick actions

cmd+k|ctrl+k

Navigation

Languages

c stack queue in array

Snippet info

Language

C

Visibility

public

Author

hyrious

Created

2020-06-09T12:37:37Z

Updated

2020-06-09T12:37:37Z

#include <stdio.h>
#include <stdlib.h>
#define class(a) typedef struct a a; struct a
#define make(a) (a *)malloc(sizeof(a))

// 内存
class(storage) {
    int *data;   // 数据
    size_t size; // 大小
};

void storage_init(storage *s) {
    s->size = 16;
    s->data = malloc(sizeof(int) * s->size);
}

// 倍增
void storage_enlarge(storage *s) {
    size_t size = ((s->size << 1) + s->size) >> 1;
    int *data = realloc(s->data, sizeof(int) * size);
    if (!data) {
        fprintf(stderr, "realloc error\n");
        exit(EXIT_FAILURE);
    }
    s->data = data;
    s->size = size;
}

void storage_free(storage *s) {
    free(s->data);
}

// 栈
class(stack) {
    storage s;
    size_t top;
};

void stack_init(stack *s) {
    storage_init(&s->s);
    s->top = 0;
}

int stack_empty(stack *s) {
    return s->top == 0;
}

void stack_push(stack *s, int x) {
    if (s->top == s->s.size) storage_enlarge(&s->s);
    s->s.data[s->top++] = x;
}

int stack_pop(stack *s) {
    if (stack_empty(s)) {
        fprintf(stderr, "pop empty stack\n");
        exit(EXIT_FAILURE);
    }
    return s->s.data[--s->top];
}

void stack_free(stack *s) {
    storage_free(&s->s);
}

void stack_show(stack *s) {
    printf("stack:");
    for (size_t i = s->top; i > 0; i--)
        printf(" %c", s->s.data[i - 1]);
    printf("\n");
}

// 循环数组队列
class(queue) {
    storage s;
    size_t head, tail;
};

void queue_init(queue *q) {
    storage_init(&q->s);
    q->head = q->tail = 0;
}

int queue_empty(queue *q) {
    return q->tail == q->head;
}

void queue_push(queue *q, int x) {
    if ((q->tail + 1) % q->s.size == q->head) {
        storage *s = &q->s;
        size_t size = s->size;
        s->size = ((size << 1) + size) >> 1;
        int *data = malloc(sizeof(int) * s->size);
        for (size_t i = q->head, j = 0; i != q->tail; i = (i + 1) % size)
            data[j++] = s->data[i];
        free(s->data);
        s->data = data;
        q->head = 0;
        q->tail = size - 1;
    }
    q->s.data[q->tail] = x;
    q->tail = (q->tail + 1) % q->s.size;
}

int queue_shift(queue *q) {
    if (queue_empty(q)) {
        fprintf(stderr, "pop empty queue\n");
        exit(EXIT_FAILURE);
    }
    int data = q->s.data[q->head];
    q->head = (q->head + 1) % q->s.size;
    return data;
}

void queue_free(queue *q) {
    storage_free(&q->s);
}

void queue_show(queue *q) {
    printf("queue:");
    for (size_t i = q->head; i != q->tail; i = (i + 1) % q->s.size) {
        printf(" %c", q->s.data[i]);
    }
    printf("\n");
}

void test_all(char *p, stack *s, queue *q) {
    static int n = 1;
    printf("Case #%d\n", n++);
    for (; *p; ++p) {
        stack_push(s, *p);
        queue_push(q, *p);
    }
    stack_show(s);
    queue_show(q);
    while (!stack_empty(s) && !queue_empty(q) && stack_pop(s) == queue_shift(q))
        ;
    if (!stack_empty(s) || !queue_empty(q))
        printf("not palindrome\n");
    else
        printf("palindrome\n");
    while (!stack_empty(s)) stack_pop(s);
    while (!queue_empty(q)) queue_shift(q);
    printf("\n");
}

int main(void) {
    stack s;
    stack_init(&s);

    queue q;
    queue_init(&q);

    test_all("", &s, &q);
    test_all("a", &s, &q);
    test_all("hello, world!", &s, &q);
    test_all("12345678987654321", &s, &q);

    queue_free(&q);
    stack_free(&s);

    return 0;
}
INFO