目录
前言:栈和队列是在顺序表和链表的延伸,如果前面的顺序表和链表你已经掌握了的话,栈和队列对你来说应该就是小菜一碟了。
1、栈
(1)栈的概念及结构
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶。
(2)栈的实现
栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组尾上插入数据的代价比较小。
Stack.h
#pragma once #include<stdio.h> #include<assert.h> #include<stdlib.h> #include<stdbool.h> typedef char STDataType; typedef struct Stack { STDataType* a; int top; int capacity; }SL; //初始化 void StackInit(SL* ps); //使用后销毁 void StackDestroy(SL* ps); //入栈 void StackPush(SL* ps, STDataType x); //出栈 void StackPop(SL* ps); //判断栈空 bool StackEmpty(SL* ps); //栈的大小 int StackSize(SL* ps); //栈顶元素 STDataType StackTop(SL* ps);
Stack.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "Stack.h" //初始化 void StackInit(SL* ps) { assert(ps); ps->a = NULL; ps->top = 0; ps->capacity = 0; } //使用后销毁 void StackDestroy(SL* ps) { assert(ps); free(ps->a); ps->a = NULL; ps->top = ps->capacity = 0; } //入栈 void StackPush(SL* ps, STDataType x) { assert(ps); //如果栈满增容 if (ps->top == ps->capacity) { STDataType newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2; STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newcapacity); if (tmp == NULL) { printf("realloc fail\n"); exit(-1); } else { ps->a = tmp; ps->capacity = newcapacity; } } ps->a[ps->top] = x; ps->top++; } //出栈 void StackPop(SL* ps) { assert(ps); assert(ps->top > 0); ps->top--; } //判断栈空 bool StackEmpty(SL* ps) { assert(ps); return (ps->top == 0); } //栈的大小 int StackSize(SL* ps) { assert(ps); return ps->top; } //栈顶元素 STDataType StackTop(SL* ps) { assert(ps); assert(ps->top > 0); return ps->a[ps->top-1]; }
test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "Stack.h" //void test() //{ // SL st; // // StackInit(&st); // StackPush(&st, 1); // StackPush(&st, 2); // //StackPush(&st, 3); // //StackPush(&st, 4); // // printf("%d\n", StackTop(&st)); // // StackPop(&st); // // StackPush(&st, 3); // StackPush(&st, 4); // // while (!StackEmpty(&st)) // { // printf("%d ", StackTop(&st)); // StackPop(&st); // } // printf("\n"); // // StackDestroy(&st); // //} bool isValid(char* s) { SL st; StackInit(&st); while (*s) { if (*s == '(' || *s == '{' || *s == '[') { StackPush(&st, *s); s++; } else { if (StackEmpty(&st)) return false; char top = StackTop(&st); StackPop(&st); if ((*s == ')' && top != '(') || (*s == ']' && top != '[') || (*s == '}' && top != '{')) { StackDestroy(&st); return false; } else { s++; } } } //栈为空,说明左括号都匹配完了 bool ret = StackEmpty(&st); StackDestroy(&st); return ret; } int main() { //test(); char a[] = { "{()}" }; bool ret = isValid(a); printf("%d", ret); return 0; }
2、队列
(1)队列的概念及结构
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)
入队列:进行插入操作的一端称为队尾
出队列:进行删除操作的一端称为队头
![]()
(2)队列的实现
Queue.h
#pragma once #include<stdio.h> #include<assert.h> #include<stdbool.h> #include<stdlib.h> typedef int QDataType; typedef struct QueueNode { QDataType data; struct QueueNode* next; }QNode; typedef struct Queue { QNode* head; QNode* tail; }Queue; //初始化 void QueueInit(Queue* pq); //销毁 void QueueDestroy(Queue* pq); //入队 void QueuePush(Queue* pq, QDataType x); //出队 void QueuePop(Queue* pq); //判断队空 bool QueueEmpty(Queue* pq); //队的大小 size_t QueueSize(Queue* pq); //队长 QDataType QueueFront(Queue* pq); //队尾 QDataType QueueBack(Queue* pq);
Queue.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "Queue.h" //初始化 void QueueInit(Queue* pq) { assert(pq); pq->head = pq->tail = NULL; } //销毁 void QueueDestroy(Queue* pq) { assert(pq); QNode* cur = pq->head; while (cur) { QNode* next = cur->next; free(cur); cur = next; } pq->head = pq->tail = NULL; } //入队 void QueuePush(Queue* pq, QDataType x) { assert(pq); QNode* newnode = (QNode*)malloc(sizeof(QNode)); assert(newnode); newnode->data = x; newnode->next = NULL; if (pq->tail == NULL) { pq->head = pq->tail = newnode; } else { pq->tail->next = newnode; pq->tail = newnode; } } //出队 void QueuePop(Queue* pq) { assert(pq); assert(pq->head && pq->tail); if (pq->head->next == NULL) { free(pq->head); pq->head = pq->tail = NULL; } else { QNode* next = pq->head->next; free(pq->head); pq->head = next; } } //判断队空 bool QueueEmpty(Queue* pq) { assert(pq); //return (pq->head == NULL) && (pq->tail == NULL); return pq->head == NULL; } //队的大小 size_t QueueSize(Queue* pq) { assert(pq); QDataType size = 0; QNode* cur = pq->head; while (cur) { size++; cur = cur->next; } return size; } //队长 QDataType QueueFront(Queue* pq) { assert(pq); assert(pq->head); return pq->head->data; } //队尾 QDataType QueueBack(Queue* pq) { assert(pq); assert(pq->tail); return pq->tail->data; }
Test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "Queue.h" void test() { Queue q; QueueInit(&q); QueuePush(&q, 1); QueuePush(&q, 2); QueuePush(&q, 3); QueuePush(&q, 4); printf("%d\n", QueueFront(&q)); printf("%d\n", QueueBack(&q)); /*while (!QueueEmpty(&q)) { printf("%d ", QueueFront(&q)); QueuePop(&q); } printf("\n");*/ QueuePop(&q); while (!QueueEmpty(&q)) { printf("%d ", QueueFront(&q)); QueuePop(&q); } printf("\n"); QueueDestroy(&q); } int main() { test(); return 0; }
栈和队列到此结束,若想再进一步,请关注下章讲解!