栈和队列

栈和队列

目录

栈(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]的内存

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值