C语言实现栈和队列
文章目录
一、栈和队列的简介
栈和队列都是数据结构的重要组成部分,但他们却有截然不同的特点
栈(Stack):又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。
其特点是“先进后出”
队列(Queue):队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
其特点是“先入先出”
二、实现思路
栈和队列都能通过数组和链表实现,但基于两者的结构特点分析优劣
我们常用数组来实现栈,用链表来实现队列
1.栈
根据栈的“先入后出”的特点我们可以实现出基本结构
typedef int STDataType;
typedef struct Stack
{
STDataType* data;//动态数组
int Top;//栈顶
int capacity;//栈的最大容量
}Stack;
1.1 栈初始化
写出结构后,我们应该对其结构进行初始化
初始化时要尤为注意Top的位置指向什么位置
void STInit(Stack* pc)
{
assert(pc);
pc->data = NULL;
//栈顶指向下一个位置
pc->Top = 0;
pc->capacity = 0;
}
1.2 栈销毁
void STDestroy(Stack* pc)
{
assert(pc);
pc->capacity = 0;
pc->Top = 0;
pc->data = NULL;
//假设使用者置空
free(pc->data);
}
1.2 入栈
要注意栈满的情况,需要进行判定并扩容
void STPush(Stack* pc, STDataType x)
{
assert(pc);
if (pc->capacity == pc->Top)
{
int newcapacity = pc->capacity == 0 ? 4 : pc->capacity * 2;
pc->capacity = newcapacity;
STDataType* tmp = (int*)realloc(pc->data, pc->capacity * sizeof(int));
if (tmp == NULL)
{
perror("ralloc fail");
return;
}
else
{
pc->data = tmp;
}
}
pc->data[pc->Top] = x;
pc->Top++;
}
1.3 出栈
要注意空栈的情况,需要进行判定
bool STEmpty(Stack* pc)
{
assert(pc);
return pc->Top == 0;
}
void STPop(Stack* pc)
{
assert(pc);
assert(!STEmpty(pc));
pc->Top--;
}
1.4 栈顶数据
STDataType STTop(Stack* pc)
{
assert(pc);
assert(!STEmpty(pc));
return pc->data[pc->Top - 1];
}
1.5 栈大小
int STSize(Stack* pc)
{
assert(pc);
return pc->Top;
}
1.6 实现代码
Stack.h
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#include <stdlib.h>
typedef int STDataType;
typedef struct Stack
{
STDataType* data;
int Top;
int capacity;
}Stack;
//栈初始化
void STInit(Stack* pc);
//栈销毁
void STDestroy(Stack* pc);
//入栈
void STPush(Stack* pc, STDataType x);
//出栈
void STPop(Stack* pc);
//栈顶数据
STDataType STTop(Stack* pc);
//判空
bool STEmpty(Stack* pc);
//栈大小
int STSize(Stack* pc);
Stack.c
#include "Stack.h"
void STInit(Stack* pc)
{
assert(pc);
pc->data = NULL;
//栈顶指向下一个位置
pc->Top = 0;
pc->capacity = 0;
}
void STDestroy(Stack* pc)
{
assert(pc);
pc->capacity = 0;
pc->Top = 0;
pc->data = NULL;
//假设使用者置空
free(pc->data);
}
void STPush(Stack* pc, STDataType x)
{
assert(pc);
if (pc->capacity == pc->Top)
{
int newcapacity = pc->capacity == 0 ? 4 : pc->capacity * 2;
pc->capacity = newcapacity;
STDataType* tmp = (int*)realloc(pc->data, pc->capacity * sizeof(int));
if (tmp == NULL)
{
perror("ralloc fail");
return;
}
else
{
pc->data = tmp;
}
}
pc->data[pc->Top] = x;
pc->Top++;
}
bool STEmpty(Stack* pc)
{
assert(pc);
return pc->Top == 0;
}
void STPop(Stack* pc)
{
assert(pc);
assert(!STEmpty(pc));
pc->Top--;
}
STDataType STTop(Stack* pc)
{
assert(pc);
assert(!STEmpty(pc));
return pc->data[pc->Top - 1];
}
int STSize(Stack* pc)
{
assert(pc);
return pc->Top;
}
2.队列
同上,我们根据队列的特征定义结构
typedef int QEDataType;
typedef struct QueueNode
{
QEDataType data;
struct QueueNode* next;
}QueueNode;
typedef struct Queue
{
QueueNode* phead;//队头
QueueNode* ptail;//队尾
int size;
}Queue;
1.1 队列初始化
void QueueInit(Queue* q)
{
assert(q);
q->phead = NULL;
q->ptail = NULL;
q->size = 0;
}
1.2 队尾入队列
void QueuePush(Queue* q, QEDataType x)
{
assert(q);
QueueNode* tmp = (QueueNode*)malloc(sizeof(QueueNode));
if (tmp == NULL)
{
perror("malloc fail");
return;
}
else
{
tmp->next = NULL;
tmp->data = x;
}
if (q->phead == NULL)
{
q->phead = q->ptail = tmp;
}
else
{
q->ptail->next = tmp;
q->ptail = tmp;
}
q->size++;
}
1.3 判空
int QueueEmpty(Queue* q)
{
assert(q);
if (q->size == 0)
{
return 1;
}
else
{
return 0;
}
}
1.4 队头出队列
尤为注意空队列的时候尾指针置空
void QueuePop(Queue* q)
{
assert(q);
assert(!QueueEmpty(q));
QueueNode* tmp = q->phead;
q->phead = q->phead->next;
q->size--;
if (q->phead == NULL)
{
q->ptail = NULL;
}
free(tmp);
}
1.5 获取队列头部元素
QEDataType QueueFront(Queue* q)
{
assert(q);
return q->phead->data;
}
1.6 获取队列队尾元素
QEDataType QueueBack(Queue* q)
{
assert(q);
return q->ptail->data;
}
1.7 获取队列中有效元素个数
int QueueSize(Queue* q)
{
assert(q);
return q->size;
}
1.8 销毁队列
void QueueDestroy(Queue* q)
{
assert(q);
while (!QueueEmpty(q))
{
QueuePop(q);
}
q->size = 0;
}
1.9 实现代码
Queue.h
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#include <stdlib.h>
typedef int QEDataType;
typedef struct QueueNode
{
QEDataType data;
struct QueueNode* next;
}QueueNode;
typedef struct Queue
{
QueueNode* phead;
QueueNode* ptail;
int size;
}Queue;
//队列初始化
void QueueInit(Queue* q);
// 队尾入队列
void QueuePush(Queue* q, QEDataType data);
// 队头出队列
void QueuePop(Queue* q);
// 获取队列头部元素
QEDataType QueueFront(Queue* q);
// 获取队列队尾元素
QEDataType QueueBack(Queue* q);
// 获取队列中有效元素个数
int QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* q);
// 销毁队列
void QueueDestroy(Queue* q);
Queue.c
#include "Queue.h"
void QueueInit(Queue* q)
{
assert(q);
q->phead = NULL;
q->ptail = NULL;
q->size = 0;
}
void QueuePush(Queue* q, QEDataType x)
{
assert(q);
QueueNode* tmp = (QueueNode*)malloc(sizeof(QueueNode));
if (tmp == NULL)
{
perror("malloc fail");
return;
}
else
{
tmp->next = NULL;
tmp->data = x;
}
if (q->phead == NULL)
{
q->phead = q->ptail = tmp;
}
else
{
q->ptail->next = tmp;
q->ptail = tmp;
}
q->size++;
}
int QueueEmpty(Queue* q)
{
assert(q);
if (q->size == 0)
{
return 1;
}
else
{
return 0;
}
}
void QueuePop(Queue* q)
{
assert(q);
assert(!QueueEmpty(q));
QueueNode* tmp = q->phead;
q->phead = q->phead->next;
q->size--;
if (q->phead == NULL)
{
q->ptail = NULL;
}
free(tmp);
}
QEDataType QueueFront(Queue* q)
{
assert(q);
return q->phead->data;
}
QEDataType QueueBack(Queue* q)
{
assert(q);
return q->ptail->data;
}
int QueueSize(Queue* q)
{
assert(q);
return q->size;
}
void QueueDestroy(Queue* q)
{
assert(q);
while (!QueueEmpty(q))
{
QueuePop(q);
}
q->size = 0;
}
以上就是文章的全部内容,如果对你有帮助请点个赞和收藏吧
注:以上代码为本人所写,若存在BUG或者有不懂的地方可以私信我