栈
栈的定义
栈就类似弹夹中的子弹一样先进去,却要后出来,而最后一个进弹夹的子弹却是第一个被射出来的
栈只允许在一端进行操作 一端称为栈顶 另一端成为栈底
不含任何数据元素的栈称为空栈。栈又称为先进后出的线性表
栈的插入操作叫做进栈/压栈/入栈
栈的删除操作叫做出栈/弹栈 如上图所示
接下来就定义一个栈的结构
typedef int DataType;
typedef struct stack
{
DataType* a;
int top;//栈顶
int capacity;//容量
}stack;
初始化栈
void StackInit(stack* ps)
{
assert(ps);
ps->a = NULL;
ps->top = 0;
ps->capacity = 0;
}
入栈
void StackPush(stack* ps, DataType x)
{
assert(ps);
//检查容量
if (ps->capacity == ps->top)
{
int newcapacity = ps->capacity == 0 ? 4 : (ps->capacity) * 2;
DataType* tmp = (DataType*)realloc(ps->a, sizeof(stack) * newcapacity);//realloc如果是空指针,则该函数的行为类似于malloc
if (tmp == NULL)
{
perror("realloc fail");
exit(-1);
}
ps->a = tmp;
ps->capacity = newcapacity;
}
//入栈
ps->a[ps->top] = x;
ps->top++;
}
出栈
void StackPop(stack* ps)
{
assert(ps);
assert(ps->top > 0);
--(ps->top);
}
获取栈顶元素
DataType StackTop(stack* ps)
{
assert(ps);
//栈顶元素是top前一个
return ps->a[ps->top-1];
}
获取有效元素个数
int StackSize(stack* ps)
{
assert(ps);
return ps->top;
}
判断是否为空栈
bool StackEmpty(stack* ps)
{
assert(ps);
return ps->top == 0 ? true : false;
}
销毁栈
void StackDestory(stack* ps)
{
assert(ps);
free(ps->a);
ps->a == NULL;
ps->capacity = ps->top = 0;
}
队列
队列是之允许在一端进行插入操作 ,一段进行删除操作,插入的一段叫队尾,删除的一段叫头
队列是一种先进先出的线性表
如下图
定义一个队列
typedef int DataType;
typedef struct Qnode
{
DataType val;
struct Qnode* next;
}Qnode;
typedef struct Queue
{
Qnode* head;
Qnode* tail;
int size;//记录元素个数
}Queue;
初始化队列
void QueueInit(Queue* ps)
{
assert(ps);
ps->tail = NULL;
ps->head = NULL;
ps->size = 0;
}
入队列
void QueuePush(Queue* ps, DataType x)
{
assert(ps);
Qnode* newnode = (Qnode*)malloc(sizeof(Qnode));
if (newnode == NULL)
{
perror("malloc fail");
exit(-1);
}
newnode->val = x;
newnode->next = NULL;
//判断是否是第一次进队列(尾插)
if (ps->tail == NULL)
{
ps->head = ps->tail = newnode;
}
else
{
ps->tail->next = newnode;
ps->tail = newnode;
}
ps->size++;
}
在入队列时的思路和单链表的尾插一样 需要注意一下第一次进队列要特殊处理
出队列
void QueuePop(Queue* ps)
{
assert(ps);
//检查队列是否为空
assert(!QueueEmpty(ps));
//只有一个元素 head和tail在同一节点
if (ps->head->next == NULL)
{
free(ps->head);
ps->tail = ps->head = NULL;
}
else
{
Qnode* next = ps->head->next;
free(ps->head);
ps->head = next;
}
ps->size--;
}
在出队列时 即单链表的头删 如果只有一个节点 需要特殊处理
销毁队列
void QueueDestory(Queue* ps)
{
assert(ps);
Qnode* cur = ps->head;
while (cur != NULL)
{
Qnode* next = cur->next;
free(cur);
cur = next;
}
ps->head = ps->tail = NULL;
ps->size = 0;
}
获取队列头元素
DataType QueueFront(Queue* ps)
{
assert(ps);
//检查队列是否为空
assert(!QueueEmpty(ps));
return ps->head->val;
}
获取队列尾元素
DataType QueueBack(Queue* ps)
{
assert(ps);
//检查队列是否为空
assert(!QueueEmpty(ps));
return ps->tail->val;
}
检测队列是否为空
bool QueueEmpty(Queue* ps)
{
assert(ps);
return ps->head == NULL;
}
获取队列元素个数
int QueueSzie(Queue* ps)
{
assert(ps);
return ps->size;
}