目录
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶,另一端称为栈底。
栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。 压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。 出栈:栈的删除操作叫做出栈。出数据也在栈顶。

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的 代价比较小。

代码实现
- #pragma once
-
- #include
- #include
- #include
- #include
-
-
- typedef int STDataType;
- typedef struct Stack
- {
- STDataType* a;
- int top;
- int capacity;
- }ST;
-
- //初始化
- void STInit(ST* ps);
-
- //销毁
- void STDestroy(ST* ps);
-
- //插入
- void STPush(ST* ps, STDataType x);
-
- //删除
- void STPop(ST* ps);
-
- //返回栈顶元素
- STDataType STTop(ST* ps);
-
- //计算大小
- int STSize(ST* ps);
-
- //判断是否为空
- bool STEmpty(ST* ps);
- //初始化
- void STInit(ST* ps)
- {
- assert(ps);
- ps->a = NULL;
- ps->top = 0;
- ps->capacity = 0;
- }
-
- //销毁
- void STDestroy(ST* ps)
- {
- assert(ps);
-
- free(ps->a);
- ps->a = NULL;
- ps->top = ps->capacity = 0;
- }
- //插入
- void STPush(ST* ps, STDataType x)
- {
- assert(ps);
-
- //检查是否扩容
- if (ps->top == ps->capacity)
- {
- int newCapacity = ps->capacity == 0 ? 4 : ps->capacity *2;//扩两倍
- STDataType tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * (newCapacity));//realloc也可以原地扩容
- if (tmp == NULL)
- {
- perror("realloc failed");
- exit(-1);
- }
- ps->a = tmp;
- ps->capacity = newCapacity;
- }
-
- //插入
- ps->a[ps->top] = x;
- ps->top++;//top是栈顶的下一个位置
- }

- //删除
- void STPop(ST* ps)
- {
- assert(ps);
- assert(ps->top > 0);
- ps->top--;
- }
- //返回栈顶元素
- STDataType STTop(ST* ps)
- {
- assert(ps);
- assert(ps->top > 0);
- return ps->a[ps->top - 1];
- }
- //计算大小
- int STSize(ST* ps)
- {
- assert(ps);
- return ps->top;
- }
-
- //判断是否为空
- bool STEmpty(ST* ps)
- {
- assert(ps);
- return ps->top == 0;
- }
- #include "Stack.h"
-
- void TestStack1()
- {
- ST st;
- STInit(&st);
- STPush(&st, 1);
- STPush(&st, 2);
- STPush(&st, 3);
- STPush(&st, 4);
- STPush(&st, 5);
-
- while (!STEmpty(&st))
- {
- printf("%d ", STTop(&st));
- STPop(&st);
- }
- printf("\n");
-
- STDestroy(&st);
- }
-
- int main()
- {
- TestStack1();
-
- return 0;
- }

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数 组头上出数据,效率会比较低

- #pragma once
- #include
- #include
- #include
- #include
-
- typedef int QDataType;
- typedef struct QueueNode
- {
- struct QueueNode* next;
- QDataType data;
- }QNode;
-
- typedef struct Queue
- {
- QNode* head;
- QNode* tail;
- int size;
- }Que;
-
- //初始化
- void QueueInit(Que* pq);
-
- //销毁
- void QueueDestroy(Que* pq);
-
- //插入
- void QueuePush(Que* pq, QDataType x);
-
- //删除
- void QueuePop(Que* pq);
-
- //返回第一个
- QDataType QueueFront(Que* pq);
-
- //返回末尾
- QDataType QueueBack(Que* pq);
-
- //是否为空
- bool QueueEmpty(Que* pq);
-
- //计算大小
- int QueueSize(Que* pq);
-
-
- //初始化
- void QueueInit(Que* pq)
- {
- assert(pq);
- pq->head = pq->tail = NULL;
- pq->size = 0;
- }
-
- //销毁
- void QueueDestroy(Que* pq)
- {
- assert(pq);
- QNode* cur = pq->head;
- while (cur)
- {
- QNode* next = cur->next;
- free(cur);
- cur = next;
- }
- pq->head = pq->tail = NULL;
- pq->size = 0;
- }
- //插入
- void QueuePush(Que* pq, QDataType x)
- {
- assert(pq);
-
- QNode* newnode = (QNode*)malloc(sizeof(QNode));
- if (newnode == NULL)
- {
- perror("malloc fail");
- exit(-1);
- }
- newnode->data = x;
- newnode->next = NULL;
-
- if (pq->tail == NULL)
- {
- pq->head = pq->tail = newnode;
- }
- else
- {
- pq->tail->next = newnode;
- pq->tail = newnode;
- }
-
- pq->size++;
- }

- //删除
- void QueuePop(Que* pq)
- {
- assert(pq);
- assert(!QueueEmpty(pq));
-
- if (pq->head->next == NULL)
- {
- free(pq->head);
- pq->head = pq->tail = NULL;
- }
- else
- {
- QNode* newhead = pq->head->next;
- free(pq->head);
- pq->head = newhead;
- }
-
- pq->size--;
- }

- QDataType QueueFront(Que* pq)
- {
- assert(pq);
- assert(!QueueEmpty(pq));
-
- return pq->head->data;
- }
-
- QDataType QueueBack(Que* pq)
- {
- assert(pq);
- assert(!QueueEmpty(pq));
-
- return pq->tail->data;
- }
- bool QueueEmpty(Que* pq)
- {
- assert(pq);
-
- return pq->head == NULL;
- }
- int QueueSize(Que* pq)
- {
- assert(pq);
-
- return pq->size;
- }
- #define _CRT_SECURE_NO_WARNINGS 1
- #include"Queue.h"
-
-
- Test()
- {
- Que pq;
- QueueInit(&pq);
- QueuePush(&pq, 1);
- QueuePush(&pq, 2);
- QueuePush(&pq, 3);
- QueuePush(&pq, 4);
- QueuePush(&pq, 5);
- while(!QueueEmpty(&pq))
- {
- printf("%d ", QueueFront(&pq));
- QueuePop(&pq);
- }
- QueueDestroy(&pq);
-
- }
-
-
- int main()
- {
- Test();
- return 0;
- }

栈和队列感觉就是链表和顺序表的变形, 很容易理解,下一章我会对栈和队列的OJ进行整理和讲解, 继续加油!