其实栈(Stack)就相当于一个大桶,东西只能从下面往上放,取得时候也只能自上至下的取。传说中的栈为LIFO,与队列FIFO(First-in,First-out)相对应。而栈顶叫做TOP ,栈底叫做Bottom。
我们对栈进行储存的时候需要用到push,进栈的时侯需要将top加1,退栈的时候需要top减1.
1、置空栈
void initstack(seqstack *s)
{
s–>top=-1;
}
2、判断栈空
int stackempty(seqstack *s)
{
return(s–>top==-1);
}
3、退栈
datatype pop(seqstack *s)
{
if(stackempty(s))
error(“stack underflow”);
x=s–>data[top];
s–>top--;
return(x)
//return(s–>data[s–>top--]);
}
用代码实现栈的各种操作
#include
#include
#include
using namespace std;
typedef int ElemType;
const int STACK_SIZE = 1;
struct Stack{
ElemType *base;
ElemType *top;
int size;
};
void InitStack(Stack *&s){
s = new Stack ;
s->base = new ElemType [STACK_SIZE];
s->top = s->base; // 刚开始的时候就是栈顶指向栈底
s->size = STACK_SIZE;
}
void Push(Stack *&s,ElemType e){
//如果栈满,动态增容,容量增大STACK_SIZE
if(s->top-s->base >= s->size ){
//s->base = (ElemType *)realloc(s->base,(s->size+STACK_SIZE)*sizeof(ElemType)); c++弃用了realloc
cout<<"空间不够,重新申请中,请等待:\nPlease wait..."<
ElemType *tem = new ElemType [s->size];
for(int i=0;i
tem[i] = s->base[i];
delete [] s->base;
s->base = tem;
s->top = s->base + s->size; //重新设置栈顶 (注意之前已经满了)
s->size = s->size + STACK_SIZE; //重新设置最大容量
cout<<"申请成功。"<
*(s->top) = e;
++(s->top);
}
void Pop(Stack *&s){
if(s->top != s->base)
cout<<(*--(s->top))<
return ; // 如果没有元素的话
}
//拿到当前容量
int NowSize(Stack *s){
return s->top - s->base;
}
//清空栈
void ClearStack(Stack *&s){
s->top = s->base;
}
void DestroyStack(Stack *&s){
s->size = 0;
delete [] s->base;
//delete [] s->top; 等效的
s->base = s->top = NULL; //栈顶和栈底重新指向NULL
}
int main(){
Stack *stack= NULL;
InitStack(stack);
Push(stack,1);
Push(stack,2);
cout<<"Now size is: "<
cout<<"Now size is: "<
cout<<"Now size is: "<
cout<< stack<
}
栈中需要注意的问题
1. 常量必须在构造函数的初始化列表里面初始化。
class A { const int size = 0; }; 是错误的。 需要改成 class A{ A(){ const int size = 10; } };
或者改成 class A { static const int size = 10; };
2.基类的析构函数必须是虚函数。因为这样处理后,所有子类的析构函数都将会被自动变为virtual类型,这就保证了在任何情况下,不会出现由于析构函数未被调用而导致的内存泄露。
3.单参数的构造函数如果不添加explicit关键字,会定义一个隐含的类型转换,添加explicit关键字会消除这种类型转换。
4.如果类中包含指针的话,一般需要编写拷贝构造函数和拷贝赋值运算符,以避免浅拷贝。
队列
1、队列(Queue)与栈一样,是一种线性存储结构,它具有如下特点:
(1)队列中的数据元素遵循“先进先出”(First In First Out)的原则,简称FIFO结构;
(2)在队尾添加元素,在队头删除元素。
2、队列的相关概念:
(1)队头与队尾: 允许元素插入的一端称为队尾,允许元素删除的一端称为队头;
(2)入队:队列的插入操作;
(3)出队:队列的删除操作。
3、队列的操作:
(1)入队: 通常命名为push()
(2)出队: 通常命名为pop()
(3)求队列中元素个数
(4)判断队列是否为空
(5)获取队首元素
4、队列的分类:
(1)基于数组的循环队列(循环队列)
(2)基于链表的队列(链队列)
5、实例分析
C++队列queue模板类的定义在
代码实现:
队列中由于是先进先出,push即在队尾插入一个元素,如:
queue
q.push("Hello World!");
q.push("China");
cout< 将队列中最靠前位置的元素拿掉,是没有返回值的void函数。如: queue q.push("Hello World!"); q.push("China"); q.pop(); cout< 返回队列中元素的个数,返回值类型为unsigned int。如: queue cout< q.push("Hello World!"); q.push("China"); cout< 判断队列是否为空的,如果为空则返回true。如 queue cout< q.push("Hello World!"); q.push("China"); cout<2. pop()
3. size()
4. empty()