栈和队列(C链表实现)

  栈和队列是两种很有用的数据结构,栈是先进后出(FILO),队列是先进先出(FIFO)。
  在迷宫求解,括号匹配,递归这些问题里,栈的应用非常广泛,而队列在操作系统的进程排队,线程池里很有用。C中没有现成的栈和队列,这里用链表来模拟一下。设计时分别用到两个结构体,将链表节点部分和控制作用的表头分开,方便管理。
   

  • 在栈的设计中,使用表头指向栈的top ,每次入栈只需将新节点指向表头,表头再指向新节点便可,出栈也是将top指向下一个节点,先前的节点释放。
#include "malloc.h"
#include "stdio.h"
#include "assert.h"

#define OK 0
#define ERRO 1

typedef int status;
typedef int SdataType;

typedef struct Node {
    SdataType data;
    Node * next;
}Node;
typedef struct Stack {
    Node * top;
    int size;
}Stack;


//新建Stack
Stack* createStack(void) {
    Stack* s = (Stack*)malloc(sizeof(Stack));
    assert(s);
    s->top = NULL;
    s->size = 0;
    return s;
}

//因为有size成员,所以不需要判空函数

//入栈函数
status push(Stack* s, SdataType value) {
    Node * p = (Node *)malloc(sizeof(Node));
    assert(p);
    p->data = value;
    p->next = s->top;
    s->top = p;
    s->size++;
    return OK;
}

status pop(Stack* s, SdataType* value) {
    if (s->size == 0) {
        printf("stack empty\n");
        return ERRO;
    }
    else
    {
        Node* p = s->top;
        *value = s->top->data;
        s->top = s->top->next;
        free(p);
        s->size--;
        return OK;
    }
}

void showStack(Stack* s) {
    assert(s);
    if (s->size == 0 ) {
        printf("stack empty\n");
    }
    else {
        Node* p = s->top;
        printf("top->");
        while (p->next) {
            printf("%d ->", p->data);
            p = p->next;
        }
        printf("%d ->end\n", p->data);

    }
}

status destroyStack(Stack *s) {
    if (s->top) {
        int i;
        Node *p = s->top;
        for (i = 0; i < s->size; i++) {
            s->top = p->next;
            free(p);
            p = s->top;
        }
        free(s);
        assert(s);
        return OK;
    }
    else
    {
        printf("stack empty\n");
        return ERRO;
    }
}
int main(int argc, char **argv) {
    Stack* s = createStack();
    push(s, 1);
    push(s, 2);
    showStack(s);
    destroyStack(s);

}
  • 对于栈来说,我们只需要管好它的栈顶就行了,但是队列的话得两头都处理,所以表头结构体加一个队尾指针。并且在队列节点中增加了一个头结点,这时为了避免每次入队的时候判断是否时第一个节点带来的多余工作,头结点中内容为空。
#include "malloc.h"
#include "stdio.h"
#include "assert.h"

#define OK 0
#define ERRO 1

typedef int status;
typedef int QdataType;

typedef struct Node {
    QdataType data;
    Node * next;
}Node;
typedef struct Queue {
    Node * head;
    Node * rear;
    int size;
}Queue;


//新建Queue
Queue* createStack(void) {
    Queue* q = (Queue*)malloc(sizeof(Queue));
    assert(q);
    Node* p = (Node*)malloc(sizeof(Node));  //头结点,其内容为空,只是为了入队时不必判断队为空
    assert(p);
    p->next = NULL;
    p->data = 0;
    q->head = q->rear = p;
    q->size = 0;
    return q;
}

//尾部入,头部出
//进队函数
status enQueue(Queue* q, QdataType value) {
    Node * p = (Node *)malloc(sizeof(Node));
    assert(p);
    p->data = value;
    p->next = NULL;
    q->rear->next = p;
    q->rear = p;
    q->size++;
    return OK;
}

status deQueue(Queue* q, QdataType* value) {
    if (q->size == 0) {
        printf("queue empty\n");
        return ERRO;
    }
    else
    {
        Node* p = q->head->next; 
        *value = q->head->next->data;
        q->head->next = q->head->next->next;
        free(p);
        q->size--;
        return OK;
    }
}

void showQueue(Queue* q) {

    if (q->size == 0 ) {
        printf("queue empty\n");
    }
    else {
        Node* p = q->head->next;
        printf("head->");
        while (p->next) {
            printf("%d ->", p->data);
            p = p->next;
        }
        printf("%d ->end\n", p->data);

    }
}

status destroyQueue(Queue *q) {
    if (q->size) {
        int i;
        Node *p = q->head;
        for (i = 0; i <= q->size; i++) {
            q->head = p->next;
            free(p);
            p = q->head;
        }
        free(q);
        return OK;
    }
    else
    {
        free(q);
        return ERRO;
    }
}
int main(int argc, char **argv) {
    Queue* q = createStack();
    QdataType a = 0;
    QdataType* data = &a;

    enQueue(q, 1);
    enQueue(q, 2);
    enQueue(q, 3);
    showQueue(q);
    deQueue(q,data);
    showQueue(q);
    destroyQueue(q);
    return OK;
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值