栈和队列
目录
栈(FILO)
栈是后进先出的数据结构。
内存中的栈区处于相对较高的地址,以地址的增长方向为上的话,栈地址是向下增长的,栈中分配局部变量空间,堆区则是向上增长的用于分配程序员申请的内存空间。
(1)实现栈的几种简单操作:入栈,出栈,判断栈是否空,是否满
(2)入栈和出栈比较重要
#include<iostream>
#include<algorithm>
#include<string.h>
#include<cstdio>
#include<cstring>
#define MAX_SIZE 10
using namespace std;
class stack {
private:
int *storage;
int max_size;
int top;
public:
// 开始的时候top为-1,便于后面栈是否为空的判断
stack() {
// 动态声明内存
this->storage = new int[MAX_SIZE];
this->max_size = MAX_SIZE;
this->top = -1;
}
// 有new必须要delete
~stack() {
delete []storage;
}
void push(int);
void pop(void);
int peek(void);
bool isEmpty(void);
bool isFull(void);
void clear(void);
};
// 直接往栈顶处堆(先++top,然后在存数据,因为top是从-1开始)
void stack::push(int data) {
if (this->isFull()) {
return;
}
this->storage[++top] = data;
}
// 从栈顶开始出来元素,不需要说删除,只需要把栈的top位置往下降即可
void stack::pop(void) {
if (this->isEmpty()) {
return;
}
this->top--;
}
// 返回栈顶元素
int stack::peek(void) {
if (this->isEmpty()) {
return 0;
}
return storage[top];
}
// 判断栈是否为空
bool stack::isEmpty(void) {
return this->top == -1;
}
// 判断栈是否已经满
bool stack::isFull(void) {
return (this->top + 1 >= this->max_size);
}
// 清空栈
void stack::clear(void) {
this->top = -1;
}
void test_stack(void) {
if (true) {
stack st;
for (int i = 0; i < 5; i++) {
st.push(i);
}
st.isEmpty() ? printf("empty\n") : printf("not empty\n");
st.isFull() ? printf("full\n") : printf("not full\n");
for (int i = 0; i < 5; i++) {
printf("%d ", st.peek());
st.pop();
}
printf("\n");
st.isEmpty() ? printf("empty\n") : printf("not empty\n");
st.isFull() ? printf("full\n") : printf("not full\n");
}
printf("\n");
if (true) {
stack st;
for (int i = 0; i < 11; i++) {
st.push(i);
}
st.isEmpty() ? printf("empty\n") : printf("not empty\n");
st.isFull() ? printf("full\n") : printf("not full\n");
for (int i = 0; i < 10; i++) {
printf("%d ", st.peek());
st.pop();
}
printf("\n");
st.isEmpty() ? printf("empty\n") : printf("not empty\n");
st.isFull() ? printf("full\n") : printf("not full\n");
}
printf("\n");
if (true) {
stack st;
for (int i = 0; i < 20; i++) {
st.push(i);
}
st.clear();
st.isEmpty() ? printf("empty\n") : printf("not empty\n");
st.isFull() ? printf("full\n") : printf("not full\n");
for (int i = 0; i < 11; i++) {
st.push(i);
}
st.isEmpty() ? printf("empty\n") : printf("not empty\n");
st.isFull() ? printf("full\n") : printf("not full\n");
for (int i = 0; i < 10; i++) {
printf("%d ", st.peek());
st.pop();
}
printf("\n");
st.isEmpty() ? printf("empty\n") : printf("not empty\n");
st.isFull() ? printf("full\n") : printf("not full\n");
}
}
int main() {
test_stack();
return 0;
}
很多需要注意的地方和自己的理解都已经作为注释了,仔细看还是不难理解的,需要多做,才能比较熟练的掌握
队列(循环队列)(FIFO)
(1)实现队列的几种简单操作,包括入队,出队,队是否为空,队是否已满,注意队头队尾的变化
(2)正是因为是循环队列,所以在这个过程中要注意每次加完head 和 rear后都要%max_size
(3)入队和出队的函数比较重要
(4)还有注意队列是否已经满的函数
class queue {
private:
int *storage;
int head; // 队头
int rear; // 队尾
int max_size;
public:
queue() {
this->storage = new int[MAX_SIZE + 1];
this->max_size = MAX_SIZE + 1; // 循环队列
this->head = 0; // 注意初始值
this->rear = 0;
}
~queue() {
delete []storage;
}
void push(int);
void pop(void);
int front(void);
int back(void);
bool isFull(void);
bool isEmpty(void);
void clear(void);
};
// 入队,队增长, 即尾部++
void queue::push(int data) {
if (this->isFull()) {
return;
}
this->storage[rear] = data;
this->rear = (this->rear + 1)%max_size;
}
// 出队,从队头开始
void queue::pop(void) {
if (this->isEmpty()) {
return;
}
this->head = (this->head + 1)%max_size;
}
int queue::front(void) {
if (this->isEmpty()) {
return 0;
}
return this->storage[head];
}
int queue::back(void) {
if (this->isEmpty()) {
return 0;
}
return storage[(rear - 1 + max_size)%max_size];
}
bool queue::isFull(void) {
return ((this->rear + 1)%this->max_size) == this->head;
}
// 判断队列是否为空
bool queue::isEmpty(void) {
return this->head == this->rear;
}
// 清空队列
void queue::clear(void) {
this->rear = this->head;
}
void test_queue(void) {
if (true) {
queue qu;
for (int i = 0; i < 5; i++) {
qu.push(i);
}
qu.isEmpty() ? printf("empty\n") : printf("not empty\n");
qu.isFull() ? printf("full\n") : printf("not full\n");
for (int i = 0; i < 5; i++) {
printf("(%d,%d) ", qu.front(), qu.back());
qu.pop();
}
printf("\n");
qu.isEmpty() ? printf("empty\n") : printf("not empty\n");
qu.isFull() ? printf("full\n") : printf("not full\n");
}
printf("\n");
if (true) {
queue qu;
for (int i = 0; i < 11; i++) {
qu.push(i);
}
qu.isEmpty() ? printf("empty\n") : printf("not empty\n");
qu.isFull() ? printf("full\n") : printf("not full\n");
for (int i = 0; i < 11; i++) {
printf("(%d,%d) ", qu.front(), qu.back());
qu.pop();
}
printf("\n");
qu.isEmpty() ? printf("empty\n") : printf("not empty\n");
qu.isFull() ? printf("full\n") : printf("not full\n");
}
printf("\n");
if (true) {
queue qu;
for (int i = 0; i < 11; i++) {
qu.push(i);
}
qu.isEmpty() ? printf("empty\n") : printf("not empty\n");
qu.isFull() ? printf("full\n") : printf("not full\n");
qu.clear();
qu.isEmpty() ? printf("empty\n") : printf("not empty\n");
qu.isFull() ? printf("full\n") : printf("not full\n");
for (int i = 0; i < 5; i++) {
qu.push(i);
}
for (int i = 0; i < 5; i++) {
printf("(%d,%d) ", qu.front(), qu.back());
qu.pop();
}
printf("\n");
qu.isEmpty() ? printf("empty\n") : printf("not empty\n");
qu.isFull() ? printf("full\n") : printf("not full\n");
}
printf("\n");
}
int main() {
test_queue();
return 0;
}
注:此代码有一个不足是:没有实现动态内存分配,即需要多少内存即分配多少内存,而是直接分配了new int[MAX_SIZE]的内存