〇.写在前面
若读者朋友们发现问题,请不吝斧正。
一.栈
1.栈的结构
(1)栈是一种特殊的线性表,它只允许从固定的一端进行插入和删除操作。进行插入和删除操作的一端叫做栈顶,另一端叫做栈底。
(2)栈的插入操作叫做入栈或者压栈,栈的删除操作叫做出栈。
(3)栈内的数据遵守LIFO(last in first out),即后进先出的原则。
(4)注意,这里的栈是数据结构的概念,与函数栈帧没有关系,只是函数栈帧也有类似后进先出的概念。
(5)栈的实现用顺序表比链表更好,因为只在一端操作,不会涉及顺序表的头插操作。
2.栈的代码实现(声明)
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int StackDataType;
typedef struct Stack
{
StackDataType* data;
//栈顶元素
StackDataType top;
int capacity;
int size;
}Stack;
//初始化
void StackInit(Stack* ps);
//检查容量
void CheckCapacity(Stack* ps);
//打印
void StackPrint(Stack* ps);
//入栈
void StackPush(Stack* ps, StackDataType x);
//出栈
void StackPop(Stack* ps);
//获得栈顶元素
StackDataType StackTop(Stack* ps);
//检查栈是否为空 为空返回1 不为空返回0
int StackEmpty(Stack* ps);
//销毁
void StackDestroy(Stack* ps);
二.队列
1.队列的结构
(1)队列与栈相反,它的插入操作在固定的一端,这一端叫做队尾;它的删除操作在固定的另一端,这一端叫做队头。
(2)队列的插入操作叫做入队,删除操作叫做出队。
(3)队列的操作遵守LILO(last in last out),即后进先出的原则。
(4)队列的实现用链表比顺序表更好,但链表同时要记录头结点和尾结点的位置。
2.队列的代码实现(声明)
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int QueueDataType;
typedef struct QueueNode
{
QueueDataType data;
struct QueueNode* next;
}QueueNode;
typedef struct Queue
{
QueueNode* head;
QueueNode* tail;
}Queue;
//初始化
void QueueInit(Queue* pq);
//打印
void QueuePrint(Queue* pq);
//入队列(尾插)
void QueuePush(Queue* pq, QueueDataType x);
//出队列(头删)
void QueuePop(Queue* pq);
//获取头部元素
QueueDataType QueueFront(Queue* pq);
//获取尾部元素
QueueDataType QueueBack(Queue* pq);
//获取队列中元素个数
int QueueSize(Queue* pq);
//判断队列是否为空 为空返回1,不为空返回0
int QueueEmpty(Queue* pq);
//销毁
void QueueDestroy(Queue* pq);
三.用两个栈实现队列
思想如下
(1)现在有两个栈,栈A和栈B。
(2)入队列时:数据入栈A。
(3)出队列时:把栈A的数据先入栈B,再出栈B的数据。
四.用两个队列实现栈
思想如下
(1)现在有两个队列,队列A和队列B。
(2)第一次入队列时:入队列A或者队列B都可以。
(3)之后入队列时:入两个队列中为空的那一个,再把另一个队列中的元素全部插入到这个队列中。
(4)出队列时:出非空的哪个队列。