栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除 操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out) 的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶。
Stack.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
typedef int STDataType;
typedef struct Stack {
STDataType* a;
int top;
int capacity;
}ST;
void StackInit(ST* ps);
void StackDestory(ST* ps);
//入栈
void StackPush(ST* ps, STDataType x);
//出栈
void StackPop(ST* ps);
//返回栈顶元素
STDataType StackTop(ST* ps);
int StackSize(ST* ps);
bool StackEmpty(ST* ps);
Stack.c
#include"Stack.h"
void StackInit(ST* ps) {
assert(ps);
ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
if (ps->a == NULL) {
printf("malloc fail\n");
exit(-1);
}
ps->capacity = 4;
ps->top = 0;
}
void StackDestory(ST* ps) {
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = ps->top = 0;
}
//入栈
void StackPush(ST* ps, STDataType x) {
assert(ps);
if (ps->top == ps->capacity) {
STDataType* tmp = (STDataType*)realloc(ps->a, ps->capacity * 2 * sizeof(STDataType));
if (tmp == NULL) {
printf("realloc fail\n");
exit(-1);
}
else {
ps->a = tmp;
ps->capacity *= 2;
}
}
ps->a[ps->top] = x;
ps->top++;
}
//出栈
void StackPop(ST* ps) {
assert(ps);
//防止栈空,栈空时应终止程序
assert(ps->top > 0);
ps->top--;
}
//返回栈顶元素
STDataType StackTop(ST* ps) {
assert(ps);
//防止栈空,栈空时应终止程序
assert(ps->top > 0);
return ps->a[ps->top - 1];
}
//返回栈中的数据个数
int StackSize(ST* ps) {
assert(ps);
return ps->top;
}
bool StackEmpty(ST* ps) {
assert(ps);
return ps->top == 0;
}
Stack.c中的操作在没有掌握c++时在练习题中非常实用。
队列:只允许在一端进行插入数据操作,在另一 端进行删除数据操作的特殊线性表,队列具有先 进先出FIFO(First In First Out)
入队列:进行插入操作的一端称为队尾
出队列:进行删除操作的一 端称为队头
Queue.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
typedef int QSTDataType;
typedef struct QueueNode {
struct QueueNode* next;
QSTDataType data;
}QNode;
typedef struct Queue {
QNode* head;
QNode* tail;
}Queue;
void QueueInit(Queue* pq);
void QueueDestory(Queue* pq);
//队尾入
void QueuePush(Queue* pq, QSTDataType x);
//队头出
void QueuePop(Queue* pq);
QSTDataType QueueFront(Queue* pq);
QSTDataType QueueBack(Queue* pq);
int QueueSize(Queue* pq);
bool QueueEmpty(Queue* pq);
Queue.c
#include"Queue.h"
void QueueInit(Queue* pq) {
assert(pq);
pq->head = pq->tail = NULL;
}
void QueueDestory(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, QSTDataType x) {
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL) {
printf("malloc fail\n");
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;
}
}
//队头出
void QueuePop(Queue* pq) {
assert(pq);
assert(pq->head);
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;
}
}
//
QSTDataType QueueFront(Queue* pq) {
assert(pq);
assert(pq->head);
return pq->head->data;
}
//
QSTDataType QueueBack(Queue* pq) {
assert(pq);
assert(pq->head);
return pq->tail->data;
}
//
int QueueSize(Queue* pq) {
assert(pq);
QNode* cur = pq->head;
int size = 0;
while (cur) {
++size;
cur = cur->next;
}
return size;
}
//
bool QueueEmpty(Queue* pq) {
assert(pq);
return pq->head == NULL;
}
通过test.c对上面的代码进行测试、
Test.c
#define _CRT_SECURE_NO_WARNINGS
#include"Stack.h"
#include"Queue.h"
int main(){
/*ST st;
StackInit(&st);
StackPush(&st, 1);
StackPush(&st, 2);
StackPush(&st, 3);
printf("%d\n", StackTop(&st));
StackPop(&st);
printf("%d\n", StackTop(&st));
StackPop(&st);
StackPush(&st, 4);
StackPush(&st, 5);
while (!StackEmpty(&st)) {
printf("%d\n", StackTop(&st));
StackPop(&st);
}
StackDestory(&st);*/
Queue q;
QueueInit(&q);
QueuePush(&q, 1);
QueuePush(&q, 2);
QueuePush(&q, 3);
QueuePush(&q, 4);
while (!QueueEmpty(&q)) {
printf("%d\n", QueueFront(&q));
QueuePop(&q);
}
QueueDestory(&q);
return 0;
}