欢迎来到本期频道!- - -
本期介绍《栈和队列》
定义
栈的概念
栈:一种特殊的线性表,其只能在特定的一端插入/删除数据. |
疑问:为啥是特殊的线性表?- - -只能在一端进出数据,既后进先出. |
栈顶:插入/删除数据的一端. |
栈底:与栈顶相反的另一端. |
压栈:在栈顶插入数据. |
出栈:在栈顶删除数据. |
队列的概念
队列:一种特殊线性表,其只能在一端插入数据,另一端删除数据. |
疑问:这个又特殊在哪?- - -只能一端进数据,另一端出数据,既先进先出. |
队头:删除数据的一端. |
队尾:插入数据的一端,既与对头相反的另一端. |
入队:从队尾插入数据. |
出队:从队头删除数据. |
结构
栈的结构
队列的结构
实现
栈的实现
实现栈,可以用顺序表或者链表. |
因为在尾插方面,顺序表消耗较小,我们选择顺序表实现栈. |
Stack.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<vld.h>
#include<assert.h>
#include<stdbool.h>
typedef int STdatatype;
typedef struct Stack
{
STdatatype* p;
int top;
int capacity;
}ST;
#define INIT_CAPACITY 4
void STinit(ST* st);
void STdestroy(ST* st);
void STpush(ST* st,STdatatype x);
void STpop(ST* st);
STdatatype STgettop(ST* st);
void STcheck_room(ST* st);
bool STempty(ST* st);
int STdata_quantity(ST* st);
Stack.c
#include"Stack.h"
void STinit(ST* st)
{
assert(st);
st->p = NULL;
st->top = st->capacity = 0;
}
void STdestroy(ST* st)
{
assert(st);
free(st->p);
st->top = st->capacity = 0;
}
void STpush(ST* st,STdatatype x)
{
assert(st);
STcheck_room(st);
st->p[st->top++] = x;
}
void STpop(ST* st)
{
assert(st);
assert(st->top);
st->top--;
}
STdatatype STgettop(ST* st)
{
assert(st);
assert(st->top);
return st->p[st->top - 1];
}
void STcheck_room(ST* st)
{
assert(st);
if (st->top == st->capacity)
{
int newcapacity = (st->capacity == 0) ? INIT_CAPACITY : (st->capacity * 2);
STdatatype* temp = (STdatatype*)realloc(st->p, sizeof(STdatatype) * newcapacity);
if (temp == NULL)
{
perror("STcheck_room malloc fail");
exit(1);
}
st->p = temp;
st->capacity = newcapacity;
}
}
bool STempty(ST* st)
{
assert(st);
return !st->top;
}
int STdata_quantity(ST* st)
{
assert(st);
return st->top;
}
队列的实现
实现队列,同样可以使用顺序表或者链表. |
由于顺序表在数组头部出数据时,效率较低,故我们选择链表实现队列. |
Queue.h
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include"vld.h"
#include<stdlib.h>
typedef int QDataType;
typedef struct QListNode
{
struct QListNode* next;
QDataType data;
}QNode;
typedef struct Queue
{
QNode* head;
QNode* tail;
int size;
}Queue;
void QueueInit(Queue* q);
void QueueDestroy(Queue* q);
void QueuePush(Queue* q, QDataType data);
void QueuePop(Queue* q);
QDataType QueueFront(Queue* q);
QDataType QueueBack(Queue* q);
int QueueSize(Queue* q);
int QueueEmpty(Queue* q);
Queue.c
#include"Queue.h"
void QueueInit(Queue* q)
{
assert(q);
q->head = NULL;
q->tail = NULL;
q->size = 0;
}
void QueueDestroy(Queue* q)
{
assert(q);
QNode* cur = q->head;
while (cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
q->head = q->tail = NULL;
q->size = 0;
}
void QueuePush(Queue* q, QDataType data)
{
assert(q);
QNode* new = (QNode*)malloc(sizeof(QNode));
if (new == NULL)
{
perror("QuePush malloc fail");
exit(1);
}
new->data = data;
new->next = NULL;
if (q->tail == NULL)
{
q->head=q->tail = new;
}
else
{
q->tail->next = new;
q->tail = new;
}
q->size++;
}
void QueuePop(Queue* q)
{
assert(q);
assert(q->size);
QNode* next = q->head->next;
free(q->head);
q->head = next;
q->size--;
if (q->size == 0)
{
q->head = q->tail = NULL;
}
}
QDataType QueueFront(Queue* q)
{
assert(q);
assert(q->size);
return q->head->data;
}
QDataType QueueBack(Queue* q)
{
assert(q);
assert(q->size);
return q->tail->data;
}
int QueueSize(Queue* q)
{
assert(q);
return q->size;
}
int QueueEmpty(Queue* q)
{
assert(q);
return q->size == 0;
}
总结: