文章目录
一,栈的定义
栈是限定仅在表尾进行插入和删除操作的线性表
允许插入和删除的一端称为栈顶,另一端称为栈底。不含任何数据元素的栈称为空栈。栈又称为后进先出的线性表,简称LIFO结构。
注意:
- 栈元素具有线性关系,即前驱后继关系
- 可在线性表的表尾进行插入和删除操作,这里的表尾指的是栈顶
- 栈底是固定的,最先进栈的只能在栈底
- 栈的插入操作,叫做进栈,也称压栈,入栈
- 栈的删除操作,叫做出栈,有的也叫弹栈
二,顺序栈
栈的顺序存储结构
栈是线性表的特例,栈的顺序存储是线性表顺序存储的简化,简称顺序栈
注意:
- 线性表是用数组来实现的
- 下标为
0
的一端作为栈底比较好 - 定义一个
top
变量来指示栈顶元素在数组中的位置,当栈存在一个元素时,top
等于0
, 空栈的判定条件为top = -1
- 若一个栈的长度为 5,则栈的普通情况,空栈和栈满的情况如下图所示:
顺序栈的结构定义
//顺序栈的定义
typedef struct{
Selem *base; //栈底指针
Selem *top; //栈顶指针
int Size; //栈的长度 ,栈可用的最大容量
}Haha;
new的用法
new
的作用是从自由存储为类的对象或对象数组分配内存,并将已适当分类的非零指针返回到对象。
比如:char * pchar= new char[10];
delete pchar;
例子中动态分配了10
个char
类型的内存给了pchar
,来构成一个数组。需要注意的是,分配数组采用[ ]
,如果只是单个的只要new char
就可以了。
- 注意事项:
(1)使用delete
运算符可解除分配使用new
运算符分配的内存。而且new
和delete
是成对出现的。只出现一个是错误的或不规范的写法,即使能编译通过,也会有安全隐患,可能会造成内存泄露;
(2)使用的new
与delete
要相同。也就是说如果你在new
表达式中使用了 [ ],你必须在对应的delete
表达式中使用 [ ]。
(3)使用new
为C++
类对象分配内存时,将在分配内存后调用对象的构造函数。所以如果是自己写的类的话,最好自己写个构造函数,这样会比较好。
指针
指针是一种特殊类型的变量,用于存储值的地址
- 指针是一个变量,其存储的是值的地址,而不是值本身
- 如果
home
是一个变量,则&home
是它的地址 - 假设 m 是一个指针,则 m 表示的是一个地址,
*m
表示存储在该地址的值 &
运算符来获得地址*
运算符来获得值
进栈操作
(建议结合下面代码理解)
//顺序栈的进栈,插入元素 e作为新的栈顶元素
int Push(Haha &S,Selem e){
if(S.top - S.base == S.Size) //栈满
return 0; //不可再添加新的数据元素
*(S.top ++) = e; //将元素 e 压入栈顶,栈顶指针加一
return 1; //进栈成功
}
出栈操作
时间复杂度为O(1)
//顺序栈的出栈,删除栈顶元素,返回其值
char Pop(Haha &S){
char e;
if(S.base == S.top) //栈空
return 0;
e = *(--S.top); //栈顶指针减一,同时将栈顶元素赋值给e
return e;
}
整体代码如下:
#include <iostream>
using namespace std;
#define MAX 10 //顺序栈存储空间的初始分配量
typedef int Sta; //typedef意思相当于 type define
typedef char Selem;
//顺序栈的定义
typedef struct{
Selem *base; //栈底指针
Selem *top; //栈顶指针
int Size