文章目录

  • 1.0写在前面(关于队列)
  • 1.1栈的定义
  • 1.2栈的基本操作
  • 1.3栈的常用基本操作的实现
    • 1.3.1数据类型的定义
    • 1.3.2构造一个空栈(InitStack)
    • 1.3.3插入一个元素为栈顶元素(Push)
    • 1.3.4弹出栈顶元素并返回(Pop)
    • 1.3.5返回栈顶的元素,不删除(GetTop)
    • 1.3.6判断栈是否为空(StackEmpty)
    • 1.3.7返回当前栈的大小(StackLength)
    • 1.3.8栈的操作代码的简单整合与验证
  • 1.4栈的应用举例
    • 1.4.1写在前面
    • 1.4.2 数制转换
    • 1.4.3括号匹配的检验
    • 1.4.4表达式转换(转换为后缀表达式)
    • 1.4.5迷宫问题
    • 1.4.6汉诺塔问题
  • 1.5C++中的栈(STL容器)
  • 1.6C++中的队列(STL容器)

1.0写在前面(关于队列)

本来还想写一个队列的但是,队列其实和栈差不多,队列就是先入先出,栈就是先入后出,感觉没什么好写,就水一下算惹~。唯一需要注意的是,栈如何判断满员等问题。一般可以用循环队列解决。本文以栈为主。
队列和栈一样支持pop和push两个操作,但是与栈不同,pop完成的不是取出最顶端的元素,而是取出最底端的元素。也就是说最初放入的元素能够最先被取出(这点刚好和栈相反)

// 队列的顺序存储结构(循环队列)
#define MAX_QSIZE 5 // 最大队列长度+1
typedef struct {int *base; // 初始化的动态分配存储空间int front; // 头指针,若队列不空,指向队列头元素int rear; // 尾指针,若队列不空,指向队列尾元素的下一个位置
} SqQueue;// 构造一个空队列Q
SqQueue* Q_Init() {SqQueue *Q = (SqQueue*)malloc(sizeof(SqQueue));// 存储分配失败if (!Q){exit(OVERFLOW);}Q->base = (int *)malloc(MAX_QSIZE * sizeof(int));// 存储分配失败if (!Q->base){exit(OVERFLOW);}Q->front = Q->rear = 0;return Q;
}// 销毁队列Q,Q不再存在
void Q_Destroy(SqQueue *Q) {if (Q->base)free(Q->base);Q->base = NULL;Q->front = Q->rear = 0;free(Q);
}// 将Q清为空队列
void Q_Clear(SqQueue *Q) {Q->front = Q->rear = 0;
}// 若队列Q为空队列,则返回1;否则返回-1
int Q_Empty(SqQueue Q) {if (Q.front == Q.rear) // 队列空的标志return 1;elsereturn -1;
}// 返回Q的元素个数,即队列的长度
int Q_Length(SqQueue Q) {return (Q.rear - Q.front + MAX_QSIZE) % MAX_QSIZE;
}// 若队列不空,则用e返回Q的队头元素,并返回OK;否则返回ERROR
int Q_GetHead(SqQueue Q, int &e) {if (Q.front == Q.rear) // 队列空return -1;e = Q.base[Q.front];return 1;
}// 打印队列中的内容
void Q_Print(SqQueue Q) {int p = Q.front;while (Q.rear != p) {cout << Q.base[p] << endl;p = (p + 1) % MAX_QSIZE;}
}// 插入元素e为Q的新的队尾元素
int Q_Put(SqQueue *Q, int e) {if ((Q->rear + 1) % MAX_QSIZE == Q->front) // 队列满return -1;Q->base[Q->rear] = e;Q->rear = (Q->rear + 1) % MAX_QSIZE;return 1;
}// 若队列不空,则删除Q的队头元素,用e返回其值,并返回1;否则返回-1
int Q_Poll(SqQueue *Q, int &e) {if (Q->front == Q->rear) // 队列空return -1;e = Q->base[Q->front];Q->front = (Q->front + 1) % MAX_QSIZE;return 1;
}

队列的应用

队列的应用其实有很多,最常见的就是排队的问题,排队实际上就是一个队列,先进先出。比如说银行排队等等,由于更加贴近我们平时的生活,理解起来应该也不难。

1.1栈的定义

栈(stack) 是限定仅在表尾进行插入或删除操作的线性表。因此,对栈来说,表断有其特殊的含义,称为栈顶,相应的表底称为栈底,不含元素的称为空栈

栈又称为后进先出 的线性表(LIFO结构);结构如下:

1.2栈的基本操作

Status InitStack(SqStack &S);//构造一个空栈
Status DestroyStack(SqStack &S);//摧毁一个栈
Status ClearStack(SqStack &S);//把栈置空
Status StackEmpty(SqStack S);//判断是否为空栈
Status StackLength(SqStack S);//返回栈的长度
Status GetTop(SqStack S, SElemType &e);//返回栈顶的元素
Status Push(SqStack &S, SElemType e);//插入新元素到栈顶
Status Pop(SqStack &S, SElemType &e);//从栈顶弹出一个元素
Status StackTraverse(SqStack S, Status(*visit));//从栈底依次对每个元素调用visit,一旦visit失败,则操作失败

1.3栈的常用基本操作的实现

1.3.1数据类型的定义

这里为了方便操作将元素类型定义为int类型,具体使用过程中,可以是其他数据类型。

#define OVERFLOW 0
#define OK 1
#define TRUE 1
#define FALSE 0
#define ERROR 0typedef int ElemType;
typedef int Status;typedef struct {ElemType *base;  //栈底ElemType *top;   //栈顶指针int stacksize;   //当前已分配的存储空间
} SqStrack;

1.3.2构造一个空栈(InitStack)

初始化让栈的顶部等于底部,即top == base就可以判定为此栈为空,也就是初始化空栈,当其他需要判定是否为空栈的时候也可以使用这种方法来判断。

Status InitStack(SqStack *S) {S->base = (ElemType *)malloc(sizeof(ElemType));if (!S->base) {exit(OVERFLOW);}  //申请失败S->top = S->base;S->stacksize = 1;return OK;
}

1.3.3插入一个元素为栈顶元素(Push)

当插入一个新元素的时候需要注意如果内存空间不够需要重新申请空间,否则会插入失败,同时也要注意栈顶的指针向后移动一个位置, 即*S.top = e; S.top++;或者写作*S->top++ = e;

Status Push(SqStack *S, ElemType e) {//将新的元素e插入到栈顶if (S->top - S->base >= S->stacksize) {S->base =(ElemType *)realloc(S->base, (S->stacksize + 1) * sizeof(ElemType));if (!S->base) {exit(OVERFLOW);}S->top = S->base + S->stacksize;S->stacksize = S->stacksize + 1;}  //如果空间不够就重新申请空间*S->top++ = e;return OK;
}

1.3.4弹出栈顶元素并返回(Pop)

这里需要注意判断栈是否为空,如果为空就不能成功返回值。判定方法和上面1.3.2提到的一样。

Status Pop(SqStack *S, ElemType *e) {//若栈不为空,则弹出栈顶的元素,否则返回空栈if (S->top == S->base) {printf("此时栈中为空\n");return ERROR;}*e = *(--(S->top));return OK;
}

1.3.5返回栈顶的元素,不删除(GetTop)

同理,这里也需要注意一个判断栈是否为空,空就无法返回栈顶的元素。
同时也要注意,这里不能把*e = *(S.top - 1)写成*e = *(S.top - -);,后者就变成弹出元素了,S.top--实现自减以后再赋值,会改变栈顶指针的位置

Status GetTop(SqStack S, ElemType *e) {if (S.top == S.base) {printf("此时栈中为空\n");return ERROR;}  //此时栈中为空*e = *(S.top - 1);return OK;
}

1.3.6判断栈是否为空(StackEmpty)

这里方法和前面提到的一样,不再重复赘述。

Status StackEmpty(SqStack S) {if (S.top == S.base) {printf("此时栈中为空\n");return FALSE;}return TRUE;
}

1.3.7返回当前栈的大小(StackLength)

我们可以注意到,定义结构体时,我们有一个变量stacksize其中存储的就是我们的当前栈的大小,所以这个函数只需要返回这个参数就好惹~代码参上;

int StackLength(SqStack S) { return S.stacksize; }

1.3.8栈的操作代码的简单整合与验证

/** @Author: Henry* @Date: 2020-07-04 14:48:11* @LastEditors: Henry* @LastEditTime: 2021-04-05 14:54:47*/
#include <stdio.h>
#include <stdlib.h>#define OVERFLOW 0
#define OK 1
#define TRUE 1
#define FALSE 0
#define ERROR 0typedef int ElemType;
typedef int Status;typedef struct {ElemType *base;  //栈底ElemType *top;   //栈顶指针int stacksize;   //当前已分配的存储空间
} SqStack;Status InitStack(SqStack *S) {S->base = (ElemType *)malloc(sizeof(ElemType));if (!S->base) {exit(OVERFLOW);}  //申请失败S->top = S->base;S->stacksize = 1;return OK;
}Status GetTop(SqStack S, ElemType *e) {if (S.top == S.base) {printf("此时栈中为空\n");return ERROR;}  //此时栈中为空*e = *(S.top - 1);return OK;
}Status Push(SqStack *S, ElemType e) {//将新的元素e插入到栈顶if (S->top - S->base >= S->stacksize) {S->base =(ElemType *)realloc(S->base, (S->stacksize + 1) * sizeof(ElemType));if (!S->base) {exit(OVERFLOW);}S->top = S->base + S->stacksize;S->stacksize = S->stacksize + 1;}  //如果空间不够就重新申请空间*S->top++ = e;return OK;
}Status Pop(SqStack *S, ElemType *e) {//若栈不为空,则弹出栈顶的元素,否则返回空栈if (S->top == S->base) {printf("此时栈中为空\n");return ERROR;}*e = *(--(S->top));return OK;
}int StackLength(SqStack S) { return S.stacksize; }Status StackEmpty(SqStack S) {if (S.top == S.base) {printf("此时栈中为空\n");return FALSE;}return TRUE;
}int main() {SqStack S;ElemType e;InitStack(&S);GetTop(S, &e);printf("请输入需要插入的元素:\n");int n;scanf("%d", &n);Push(&S, n);GetTop(S, &e);printf("此时栈顶的元素为:%d\n", e);printf("此时栈的大小为:%d\n", StackLength(S));Pop(&S, &e);printf("此时弹出的元素为:%d\n", e);StackEmpty(S);system("pause");return 0;
}

1.4栈的应用举例

1.4.1写在前面

为方便操作,我将栈的操作写成了头文件,这样就可以简化代码了,头文件名为my_stack

/** @Author: Henry* @Date: 2020-07-04 14:48:11* @LastEditors: Henry* @LastEditTime: 2021-04-05 15:30:01*/
#include <stdio.h>
#include <stdlib.h>#define OVERFLOW 0
#define OK 1
#define TRUE 1
#define FALSE 0
#define ERROR 0typedef struct {ElemType *base;  //栈底ElemType *top;   //栈顶指针int stacksize;   //当前已分配的存储空间
} SqStack;Status InitStack(SqStack *S) {S->base = (ElemType *)malloc(sizeof(ElemType));if (!S->base) {exit(OVERFLOW);}  //申请失败S->top = S->base;S->stacksize = 1;return OK;
}Status GetTop(SqStack S, ElemType *e) {if (S.top == S.base) {// printf("此时栈中为空\n");return ERROR;}  //此时栈中为空*e = *(S.top - 1);return OK;
}Status Push(SqStack *S, ElemType e) {//将新的元素e插入到栈顶if (S->top - S->base >= S->stacksize) {S->base =(ElemType *)realloc(S->base, (S->stacksize + 1) * sizeof(ElemType));if (!S->base) {exit(OVERFLOW);}S->top = S->base + S->stacksize;S->stacksize = S->stacksize + 1;}  //如果空间不够就重新申请空间*S->top++ = e;return OK;
}Status Pop(SqStack *S, ElemType *e) {//若栈不为空,则弹出栈顶的元素,否则返回空栈if (S->top == S->base) {// printf("此时栈中为空\n");return ERROR;}*e = *(--(S->top));return OK;
}int StackLength(SqStack S) { return S.stacksize; }Status StackEmpty(SqStack S) {if (S.top == S.base) {// printf("此时栈中为空\n");return TRUE;}return FALSE;
}

1.4.2 数制转换

要解决这个问题,首先我们要知道进制转换是怎么实现的。如下:
我们不难发现,在十进制数转换为X进制数的过程中,除以进制数,倒写余数,先得到的数后输出,这就类似于我们的栈。所以我们可以用栈实现,下面以10->2为例。

/** @Author: Henry* @Date: 2020-07-04 14:48:11* @LastEditors: Henry* @LastEditTime: 2021-04-05 15:29:27*/
typedef int ElemType;
typedef int Status;#include "my_stack.h"int main() {int num;printf("请输入一个需要转换为 二进制 的 十进制 数:\n");scanf("%d", &num);int temp = num;  //保存num//输入一个需要转换为2进制的数字SqStack S;InitStack(&S);//先初始化一个空栈while (num > 0) {Push(&S, num % 2);  //把取模得到的数字入栈num = num / 2;      //更新num的值}while (!StackEmpty(S)) {//当栈非空,输出栈顶的元素,即逆序输出,倒写余数int e;Pop(&S, &e);printf("%d", e);}printf("\n");system("pause");return 0;
}

结果验证正确

1.4.3括号匹配的检验

假设表达式中允许包含两种括号,圆括号和方括号,其嵌套的顺序随意,即([]())或者[([][])]等均为正确的格式。

我们可以用发现,这个可以先把左括号入栈,如果出现了匹配的右括号,就把左括号出栈,就可以实现括号的匹配了,如果最后没有元素入栈了,但是栈非空,说明没有匹配成功,再者就是栈空了,但是有右括号要入栈,则匹配失败,那么按照这种思路来就很简单了。

/** @Author: Henry* @Date: 2020-07-04 14:48:11* @LastEditors: Henry* @LastEditTime: 2021-04-05 16:03:37*/
typedef char ElemType;
typedef int Status;
#include "my_stack.h"int main() {while (1) {char s[+10086];scanf("%s", s);SqStack S;InitStack(&S);  //初始化一个栈int flag = 1;   //用于标记是否匹配成功for (int i = 0; s[i] != '\0'; i++) {if (StackEmpty(S) && ((s[i] == ')') || (s[i] == ']'))) {flag = 0;break;  //匹配失败了就没必要继续匹配下去了}  //如果当前栈为空,下一个需要匹配的为右括号,则匹配失败else if (((s[i] == '(') || (s[i] == '['))) {//如果是左括号,则入栈,需要匹配Push(&S, s[i]);} else if ((s[i] == ')' || s[i] == ']')) {char e;GetTop(S, &e);if (e == '(' && s[i] == ')') {Pop(&S, &e);} else if (e == '[' && s[i] == ']') {Pop(&S, &e);} else {flag = 0;}}}if (!StackEmpty(S) && flag == 1) {flag = 0;}  //如果栈没有空,而且之前的匹配成功了,则匹配失败,因为还有部分无法匹配。if (flag) {printf("YES\n");} else {printf("NO\n");}printf("\n");}system("pause");return 0;
}

结果验证正确:

1.4.4表达式转换(转换为后缀表达式)

表达式求值中最困难的还是将表达式转换为逆波兰式,即后缀表达式
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。
比如2+3*(7-4)+8/4转换为后缀表达式为2 3 7 4 - * + 8 4 / +
具体的转换过程如下:
①:先算7-4写作后缀表达式为7 4 -为了更好理解将‘7 4 -’记作T
②:再算3*T 和 8/4 记作 ‘3 T *’ 和 ‘8 4 /’ 分别记作 AB
③:再计算2+A,为:‘2 A +’记作C
④:再计算C + B,为:C B +
⑤:最后将所有的带会原式为:2 3 7 4 - * + 8 4 / +(即把C用2 A +带入, B用8 4 /带入,然后A再用3 T * 带入,直到不能再带入)

我们不难发现:
如果要输出后缀表达式,我们只需要按照优先级来计算即可,先计算优先级高的,因此我们可以用栈来模拟(如果单纯输出后缀表达式,只需要一个操作符栈即可)下方代码即为直接输出,同时也没有使用#作为开始和结束符号,为了更好理解,图解上使用了队列和#来解释:
下面以输出后缀表达式为例:

/** @Author: Henry* @Date: 2021-04-09 19:26:32* @LastEditors: Henry* @LastEditTime: 2021-04-10 14:47:53*///函数操作在此不表int numOP(char Op) {if (Op == '-' || Op == '+') {return 1;} else if (Op == '*' || Op == '/') {return 2;} else if (Op == '(' || Op == ')') {return 3;}
}  //设置运算优先级int main() {char s[21];scanf("%s", s);SqStack OP;InitStack(&OP);int first = 1;for (int i = 0; i < strlen(s); i++) {if (((i == 0 || s[i - 1] == '(') && (s[i] == '+' || s[i] == '-')) ||(s[i] >= '0' && s[i] <= '9') || (s[i] == '.')) {if (!first) {printf(" ");}if (s[i] != '+') {printf("%c", s[i]);}while (s[i + 1] == '.' || (s[i + 1] >= '0' && s[i + 1] <= '9')) {i++;printf("%c", s[i]);}first = 0;} else {if (s[i] == ')') {while (!StackEmpty(OP) && GetTop(OP) != '(') {printf(" %c", GetTop(OP));Pop(&OP);}Pop(&OP);} else if (StackEmpty(OP) || numOP(s[i]) > numOP(GetTop(OP))) {Push(&OP, s[i]);} else {while (!StackEmpty(OP) && GetTop(OP) != '(') {printf(" %c", GetTop(OP));Pop(&OP);}Push(&OP, s[i]);}}}while (!StackEmpty(OP)) {printf(" %c", GetTop(OP));Pop(&OP);}system("pause");return 0;
}

1.4.5迷宫问题

求迷宫中一条径的算法的基本思想是:递归回溯
若当前位置“可通“,则纳入”当前路径”,并继续朝“下一个位置探索”,即切换“下一位置”为“当前位置”,如此反复直到出口;若当前位置“不可通”则应顺着“来向”退回到“前一通道块”,然后朝着除“来向”之外的其他方向继续探索;若该通道块的四周4个方块均“不可通”,则应从“当前路径”上删除该通道块。假设以栈S记录“当前路径”,则栈顶中存放的是“当前路径上最后一个通道块”。由此,“纳入路径”的操作即为“当前位置压入”,“从当前路径上删除前一块通道块”的操作即为“弹出”。
该问题更方便的可以直接用递归来求解,思想基本一致,故细节在此不表。以后学习图的遍历的时候还会再遇见的~
PS :实质上递归也是使用了栈,调用的是系统栈,返回即出栈。

1.4.6汉诺塔问题

大名鼎鼎的汉诺塔问题,相信学理工科的同学都不陌生吧
将塔座A上的n个圆盘移至塔座C上,并仍按同样顺序叠排,圆盘移动时必须遵循下列规则:
(1)每次只能移动一个圆盘;
(2)圆盘可以插在A、B和C中的任一塔座上;
(3)任何时刻都不能将一个较大的圆盘压在较 小的圆盘之上。

同样的这个问题也有两种解决方案:递归和栈
但实质上递归也是使用了栈,调用的是系统栈,返回即出栈。

基本思路:
首先先将n-1个点盘子移动到y轴
然后将第n个盘子移动到z轴

递归核心代码:

void move(int n, char x, char y, char z){             //将n个盘子从x借助y移动到z上//xyz代表三根柱子if( n == 1){                                                         //只有一个盘的情况下cout << x <<" --->" << z << endl;}else {move (n - 1, x, z, y);                                    //将第n-1个盘子从x借助z移动到y上cout << x <<"--->"<< z << endl;                //输出将第n个盘子从x移动到z上move (n - 1, y, x, z);                                    //将第n-1个盘子从y借助x移动到z上}
}

栈的核心代码:

int hanoi(int n,StackType* x,StackType* y,StackType* z)
{if(1==n){move(x,z);printf("from %c to %c\n",x->name,z->name);return 1;}hanoi(n-1,x,z,y);//先解决n-1个盘子移到辅助柱子Y的汉洛塔问题move(x,z);//最后一个从x移到Zprintf("from %c to %c\n",x->name,z->name);hanoi(n-1,y,x,z);//解决n-1个盘子移到柱子z的汉洛塔问题return 1;
}
int move(StackType* s1,StackType* s2)
{ElemType temp;temp=pop(s1);push(s2,temp);return 1;
}

1.5C++中的栈(STL容器)

栈的基本用法
push() 向栈内压入一个新成员
pop() 从栈顶弹出一个新成员
empty()如果栈为空则返回true,否则返回false
top()返回栈顶,但是不删除成员
size()返回栈内的元素的大小
头文件“stack”

示例代码

#include<iostream>
#include<stack>
using namespace std;int main(){stack < int > stk;//入栈for( int i = 0; i < 50; i++ ){stk.push( i );}cout << "栈的大小:" << stk.size() <<endl;while (!stk.empty()){cout<<stk.top()<<endl;stk.pop();}cout << "栈的大小:" << stk.size()<<endl;return 0;
}

栈源码

#include <stdlib.h>#include <iostream>
using namespace std;#define MAXSIZE 0xfffftemplate <class type>
class my_stack {int top;type* my_s;int maxsize;public:my_stack() : top(-1), maxsize(MAXSIZE) {my_s = new type[maxsize];if (my_s == NULL) {cerr << "动态存储分配失败!" << endl;exit(1);}}my_stack(int size) : top(-1), maxsize(size) {my_s = new type[maxsize];if (my_s == NULL) {cerr << "动态存储分配失败!" << endl;exit(1);}}~my_stack() { delete[] my_s; }//是否为空bool Empty();//压栈void Push(type tp);//返回栈顶元素type Top();//出栈void Pop();//栈大小int Size();
};template <class type>
bool my_stack<type>::Empty() {if (top == -1) {return true;} elsereturn false;
}template <class type>
type my_stack<type>::Top() {if (top != -1) {return my_s[top];} else {cout << "栈空\n";exit(1);}
}template <class type>
void my_stack<type>::Push(type tp) {if (top + 1 < maxsize) {my_s[++top] = tp;} else {cout << "栈满\n";exit(1);}
}template <class type>
void my_stack<type>::Pop() {if (top >= 0) {top--;} else {cout << "栈空\n";exit(1);}
}template <class type>
int my_stack<type>::Size() {return top + 1;
}

1.6C++中的队列(STL容器)

头文件“queue”

//front 是用来访问队列最底部的元素的
#include<bits/stdc++.h>
#include<queue>
using namespace std;
int main(){//关闭cin同步,此时速度会比scanf()还快。而且输入方便std::ios::sync_with_stdio(false);queue<int>que ;que.push(1);que.push(2);que.push(3);cout << que.front() << endl;//输出1que.pop();cout << que.front() << endl;//输出2;que.pop();cout << que.front() << endl;que.pop();return 0;
}

队列源码

#ifndef QUEUE_H_
#define QUEUE_H_
#include <iostream>
template <class T>
struct Node {T data;Node<T>* next;
};
template <class T>
class Queue {private:Node<T>* front;Node<T>* rear;public:Queue();~Queue();void EnQueue(T x);void Delete();bool Empty();T GetFront();void Print();
};
template <class T>
Queue<T>::Queue() {front = rear = new Node<T>;front->next = nullptr;
}
template <class T>
Queue<T>::~Queue() {while (front) {rear = front->next;delete front;front = rear;}delete rear;
}
template <class T>
void Queue<T>::EnQueue(T x) {Node<T>* p = new Node<T>;p->data = x;rear->next = p;rear = p;rear->next = nullptr;
}
template <class T>
void Queue<T>::Delete() {Node<T>* p = front->next;front->next = p->next;delete p;
}
template <class T>
bool Queue<T>::Empty() {return front == rear ? true : false;
}
template <class T>
T Queue<T>::GetFront() {return front->next->data;
}
template <class T>
void Queue<T>::Print() {Node<T>* p = front->next;while (p) {std::cout << p->data << " ";p = p->next;}std::cout << std::endl;
}
#endif  // !QUEUE_H_

数据结构-day2-栈(先进后出)和队列(先进先出)-C/C++相关推荐

  1. 数据结构 - 单调栈、单调队列

    单调栈:每日温度 请根据每日 气温 列表 temperatures ,请计算在每一天需要等几天才会有更高的温度.如果气温在这之后都不会升高,请在该位置用 0 来代替 单调栈基本只处理NGE问题(Nex ...

  2. java 栈 先进后出_栈先进后出,堆先进先出

    1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. 2. 栈的优势是,存取速度比堆要快,仅次于直接位于C ...

  3. php2个栈写一个队列,【数据结构】栈面试题--两个栈实现一个队列

    首先我们必须清楚,栈先进后出,队列先进先出.这道他们各自的特点以后,我们用两个栈来实现1个队列. 下边给出图片: 下边给出代码: template class Queue { public: void ...

  4. LeetCode-----用两个栈实现一个队列

    知识点: 栈----先进后出,队列–先进先出 题目 用两个栈实现一个队列.队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删 ...

  5. 数据结构:栈和列之如何用两个队列实现一个栈?两个栈实现一个队列?

    1.栈和队列分析 栈是一种特殊的线性表.其特殊性在于限定插入和删除数据元素的操作只能在线性表的一端进行 队列(Queue)也是一种运算受限的线性表,它的运算限制与栈不同,是两头都有限制,插入只能在表的 ...

  6. java 栈和队列实现迷宫代码_算法图解:如何用两个栈实现一个队列?

    本文已收录至 https://github.com/vipstone/algorithm <算法图解>系列. 队列和栈是计算机中两个非常重要的数据结构,经过前面的学习(<队列> ...

  7. 用栈来表示队列,用队列来表示栈

    这个问题总的栈和队列,没有自己手写,自己手写太浪费了,于是就用的java中的集合框架list下面的LinkedList 其实LinkedList既可以当做栈用,也可以当做队列来使用. 作为栈的时候,L ...

  8. 数据结构 3-0 栈与队列总结

    总结 栈和队列都可以看作对输入输出做限制的线性表.其中栈是限制了输入和输出只能在一端进行的线性表,可以将其看作向箱子里面摞书,想要取出最下面的书必须要先拿出上面的书,对应栈先进后出的特点.而队列正如其 ...

  9. 数据结构~07.栈和队列的基本概念

    数据结构~07.栈和队列的基本概念 本文是上一篇文章的后续,详情点击该链接~ 栈的定义: 栈是一种只能在一端进行插入或删除的线性表.其中,允许插入或删除的一端为栈顶(TOP).栈顶由一个称为栈顶指针的 ...

最新文章

  1. SugarCRM ListView查询中加入默认条件
  2. disk boot failure,insert system disk and press enter
  3. 机器学习填坑:你知道模型参数和超参数之间的区别吗?
  4. Notepad++使用技法
  5. 转 linux常用查看硬件设备信息命令
  6. 深入理解分布式技术 - 分布式锁的应用场景和主流方案
  7. 人工神经网络matlab啊6,MATLAB人工神经网络教程
  8. ES6笔记 -- 字符串拓展
  9. RT-Thread在github上的教程中图片显示不出来问题的解决方法
  10. vSphere Web Client使用指南之安装配置
  11. 约瑟夫环问题:猴子选大王
  12. 你看,Fastjson 漏洞也太多了吧。。
  13. 华为手机如何安装Goole play教程及安装包
  14. 各银行支付/各种支付平台/php对接支付接口心得/php h5支付接口对接
  15. git clone 的--single-branch和--depth参数
  16. 名字作诗,增添你的印象分
  17. 利用Python分析新旧页面的A/B测试结果
  18. xml解析之dom、dom4j、SAX
  19. Verilator+gtkwave
  20. 学习通课程章节被关闭时怎样查看已关闭章节内容?

热门文章

  1. 教你ios10怎么降级到ios9.3.2
  2. 计算计算机的流水线执行时间
  3. POJ 动态规划题目列表
  4. mysql错误18456_解决sql server 2008 18456 用户登录失败的方法
  5. uni-app购物车页面开发
  6. SharePoint CSOM 处理人员和组字段
  7. 计算机科学与技术答辩ppt,计算机科学与技术专业论文答辩PPT范例.ppt
  8. LocalDateTime格式化日期
  9. 理工大学ACM平台题答案关于C语言 2555 压岁钱
  10. 福建师范大学网络教育计算机考试,福建师范大学网络与继续教育学院《计算机应用基础》2020期末考试A卷(20200831135923).pdf...