栈接口的实现,直接上代码
这里讲解下有的人是把top给成-1的,栈顶指针 top 被初始化为 -1,表示栈中没有任何元素。当向栈中插入第一个元素时,我们需要将 top 的值加 1,然后将该元素存储在数组中 top 所指向的位置。此时,top 的值为 0,表示栈中有一个元素。因此,栈中有一个元素是因为插入了第一个元素。所以这里要取分一下.top给成0还是-1,根据场景应用给成多少。
栈函数的声明:
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
void STInit(ST* pst);
void STDestory(ST* pst);
void STPush(ST* pst, STDataType x);
void STPop(ST* pst);
bool STEmpty(ST* pst);
int STSize(ST* pst);
int STTop(ST* pst);
栈的初始化:
void STInit(ST* pst)
{
assert(pst);
pst->a = NULL;
pst->capacity = 0;
pst->top = 0; //Top指向栈顶数据的下一个元素
}
栈的销毁:
void STDestory(ST* pst)
{
assert(pst);
free(pst->a);
pst->a = NULL;
pst->capacity = pst->capacity = 0;
}
栈里增加元素:
void STPush(ST* pst, STDataType x)
{
if (pst->top == pst->capacity)
{
int newCapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
STDataType* tmp = (STDataType*)realloc(pst->a, newCapacity * sizeof(STDataType));
if (tmp == NULL)
{
perror("realloc fail");
return;
}
pst->a = tmp;
pst->capacity = newCapacity;
}
pst->a[pst->top] = x;
pst->top++;
}
栈里删除元素:
void STPop(ST* pst)
{
assert(pst);
assert(!STEmpty(pst));
pst->top--;
}
返回栈顶元素:
STDataType STTop(ST* pst)
{
assert(pst);
return pst->a[pst->top - 1];
}
判断栈是否为空:
bool STEmpty(ST* pst)
{
assert(pst);
return pst->top == 0;
}
返回栈的大小:
int STSize(ST* pst)
{
assert(pst);
return pst->top;
}
栈函数的简单实现:
#include"stack.h"
void TestStack()
{
ST st;
STInit(&st);
STPush(&st, 1);
STPush(&st, 2);
STPush(&st, 3);
STPush(&st, 4);
while (!STEmpty(&st))
{
printf("%d ", STTop(&st));
STPop(&st);
}
STDestory(&st);
}
int main()
{
TestStack();
return 0;
}
总结:
- 栈是一种简单但非常有用的数据结构,掌握它的基本概念、操作和实现方式对于编程学习和刷题,后面的面试都非常重要。
第二部分
队列:FIFO(First Input First Output)
定义:
队列是一种特殊的线性结构,只允许在队列的首部进行删除操作(相当于排在最前面的先买票),这称为出队(即最先来的人买完票就应该走),而在队列的尾部进行插入(后来者排对在队尾)操作,这称为入队。
队列图解:
队列函数的声明:
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int QDataType;
typedef struct QueueNode
{
struct QDataType* next;
QDataType data;
}QNode;
typedef struct Queue
{
QNode* phead;
QNode* tail;
int size;
}Queue;
void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
void QueuePush(Queue* pq, QDataType x);
void QueuePop(Queue* pq);
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
int QueueSize(Queue* pq);
bool QueueEmpty(Queue* pq);
队列函数的实现:
队列的初始化:
#include"Queue.h"
void QueueInit(Queue* pq)
{
assert(pq);
pq->phead = NULL;
pq->tail = NULL;
pq->size = 0;
}
队列的销毁:
void QueueDestroy(Queue* pq)
{
assert(pq);
QNode* cur = pq->phead;
while (cur)
{
QNode* next = cur;
free(cur);
cur = next;
}
pq->phead = NULL;
pq->tail = NULL;
pq->size = 0;
}
队列元素的添加:
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("malloc fail");
return;
}
newnode->next = NULL;
newnode->data = x;
if (pq->tail == NULL)
{
assert(pq->phead == NULL);
pq->phead = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
pq->size++;
}
队列元素的删除:
void QueuePop(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
if (pq->phead->next == NULL)
{
free(pq->phead);
pq->phead = pq->tail = NULL;
}
else
{
QNode* next = pq->phead->next;
free(pq->phead);
pq->phead = next;
}
pq->size--;
}
返回队头元素:
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->phead->data;
}
返回队尾元素:
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->tail->data;
}
返回队列的大小:
int QueueSize(Queue* pq)
{
assert(pq);
return pq->size;
}
判断队列是否为空:
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->phead == NULL && pq->tail == NULL;
}
队列函数的简单实现:
#include"Queue.h"
TestQueue()
{
Queue q;
QueueInit(&q);
QueuePush(&q, 1);
QueuePop(&q);
QueuePush(&q, 2);
QueuePush(&q, 3);
QueuePush(&q, 4);
while (!QueueEmpty(&q))
{
printf("%d ", QueueFront(&q));
QueuePop(&q);
}
printf("\n");
QueueDestroy(&q);
}
int main()
{
TestQueue();
return 0;
}
总结
- 队列先进先出
- 队列为空相当于队首等于队尾