1.栈
1.1栈的概念及结构
栈是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素的操作,进行插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入的数据在栈顶。
出栈:栈的删除操作叫做出栈,出的数据也在栈顶。
1.2栈的实现
栈的实现一般可以用数组或是链表实现,相对而言数组的结构实现更优一些,因为数组在尾上插入数据的代价比较小。
Stack.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int STDateType;
typedef struct stack
{
STDateType* a;
int top;
int capacity;
}stack;
void STInit(stack* pst);//初始化
void STDestory(stack* pst);//销毁
void STPush(stack* pst, STDateType x);//入栈
void STPop(stack* pst);//出栈
STDateType STTop(stack* pst);//取栈顶元素
bool STEmpty(stack* pst);//判空
int STSize(stack* pst);//获取元素个数
stack.c
#include"stack.h"
void STInit(stack* pst)//初始化
{
assert(pst);
pst->a = NULL;
pst->capacity = 0;
pst->top = 0;
}
void STDestory(stack* pst)//销毁
{
assert(pst);
free(pst->a);
pst->a = NULL;
pst->capacity = pst->top = 0;
}
void STPush(stack* pst, STDateType x)//入栈
{
assert(pst);
if (pst->top == pst->capacity)
{
int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
STDateType* tmp = (STDateType*)realloc(pst->a,(newcapacity *sizeof(STDateType)));
pst->a = tmp;
pst->capacity = newcapacity;
}
pst->a[pst->top++] = x;
}
void STPop(stack* pst)//出栈
{
assert(pst);
assert(pst->top > 0);
pst->top--;
}
STDateType STTop(stack* pst)//取栈顶元素
{
assert(pst);
assert(pst->top > 0);
return pst->a[pst->top - 1];
}
bool STEmpty(stack* pst)//判空
{
assert(pst);
return pst->top == 0;
}
int STSize(stack* pst)//获取元素个数
{
assert(pst);
return pst->top;
}
test.c
#include"stack.h"
int main()
{
stack st;
STInit(&st);
STPush(&st, 1);
STPush(&st, 2);
STPush(&st, 3);
STPush(&st, 4);
while (!STEmpty(&st))
{
printf("%d\n", STTop(&st));
STPop(&st);
}
STDestory(&st);
}
2.队列
2.1队列的概念和结构
队列:只允许在一端进行插入数据操作,在另一端进行删除数据的操作的特殊线性表,队列具有先进先出的特性FIFO(Frist In First Out)入队列,进行插入操作的一端称为队尾。出队列,进行删除的一端称为队头。
2.2队列的实现
queue.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
typedef int QDataType;
typedef struct QueueNode
{
QDataType val;
struct QueueNode* next;
}QueueNode;
typedef struct Queue
{
QueueNode* qhead;
QueueNode* qtail;
int size;
}Queue;
void QInit(Queue* pq);//初始化
void QDestory(Queue* pq);//销毁
void QPush(Queue* pq, QDataType x);//入队列
void QPop(Queue* pq);//出队列
bool QEmpty(Queue* pq);//判空
int QSize(Queue* pq);//队列元素个数
QDataType QueueFront(Queue* pq);//队列头元素
QDataType QueueBack(Queue* pq);//队列尾元素
queue.c
#include"queue.h"
void QInit(Queue* pq)//初始化
{
assert(pq);
pq->qhead = pq->qtail = NULL;
pq->size = 0;
}
void QDestory(Queue* pq)//销毁
{
QueueNode* cur = pq->qhead;
while (cur)
{
QueueNode* next = cur->next;
free(cur);
cur = next;
}
pq->qhead = pq->qtail = NULL;
pq->size = 0;
}
void QPush(Queue* pq, QDataType x)//入队列
{
assert(pq);
QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
if (newnode == NULL)
{
perror("malloc fail");
return;
}
newnode->next = NULL;
newnode->val = x;
if (pq->qtail == NULL)
{
pq->qhead = pq->qtail = newnode;
}
else
{
pq->qtail->next = newnode;
pq->qtail = newnode;
}
pq->size++;
}
void QPop(Queue* pq)//出队列
{
assert(pq);
assert(pq->qhead);
if (pq->qhead == pq->qtail)
{
free(pq->qhead);
pq->qhead = pq->qtail = NULL;
pq->size--;
}
else
{
QueueNode* next = pq->qhead->next;
free(pq->qhead);
pq->qhead = next;
pq->size--;
}
}
bool QEmpty(Queue* pq)//判空
{
assert(pq);
return pq->size == 0;
}
int QSize(Queue* pq)//队列元素个数
{
assert(pq);
return pq->size;
}
QDataType QueueFront(Queue* pq)//队列头元素
{
assert(pq);
assert(pq->qhead);
return pq->qhead->val;
}
QDataType QueueBack(Queue* pq)//队列尾元素
{
assert(pq);
assert(pq->qtail);
return pq->qtail->val;
}
test.c
int main()
{
Queue pq;
QInit(&pq);
QPush(&pq, 1);
QPush(&pq, 2);
QPush(&pq, 3);
QPush(&pq, 4);
printf("%d ", QueueFront(&pq));
QPop(&pq);
printf("%d ", QueueFront(&pq));
QPop(&pq);
QPop(&pq);
printf("%d ", QueueBack(&pq));
QPop(&pq);
return 0;
}