一、栈
1.栈的抽象数据类型的类型定义
1.1定义
ADT Stack{
数据对象:
D={ai|ai∈ElemSet,i=1,2,...,n,n>=0}
数据关系:
R1={<ai-1,ai>|ai-1,ai∈D,i=2,...,n}
约定an端为栈顶,a1端为栈底。
基本操作;初始化、进栈、出栈、取栈顶元素等
}ADT Stack1.2基本操作
InitStack(&S) 初始化操作
操作结果:构建一个空栈S。
DestroyStack(&S) 销毁栈操作
初始条件:栈S已存在。
操作结果:栈S被销毁。
StackEmpty(S) 判定S是否为空栈
初始条件:栈S已存在。
操作结果:若栈为空栈,则返回TRUE,否则FALSE。
StackLength(S) 求栈的长度
初始条件:栈S已存在。
操作结果:返回S的元素个数,即栈的长度。
GetTop(S,&e) 取栈顶元素
初始条件:栈S已存在且非空。
操作结果:用e返回S的栈顶元素。
ClearStack(&S) 栈置空操作
初始条件:栈S已存在。
操作结果:将S清为空栈。
Push(&S,e) 入栈操作
初始条件:栈S已存在。
操作结果:插入元素e为新的栈顶元素。
Pop(&S,&e) 出栈操作
初始条件:栈S已存在且非空。
操作结果:删除S的栈顶元素an,并用e返回其值。
2.栈的表示和实现
由于栈本身就是线性表,于是栈也有顺序存储和链式存储两种实现方式。
栈的顺序存储——顺序栈
栈的链式存储——链栈
3.顺序栈的表示和实现
3.1顺序栈
存储方式:同一般线性表的顺序存储结构完全相同
利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素。栈底一般在低地址端。
附设top指针,指示栈顶元素在顺序栈中的位置。
另设base指针,指示栈底元素在顺序栈中的位置。
但是,为了方便操作,通常top指示真正的栈顶元素之上的下标地址 |
另外,用stacksize表示栈可使用的最大容量。
3.2空栈与栈满
空栈:base==top是栈空标志 |
栈满:top-base==stacksize |
栈满是的处理方法:
|
使用数组作为顺序栈存储方式的特点:
简单、方便、但易产生溢出(数组大小固定)
上溢:栈已经满,又要压入元素
下溢:栈已经空,还要弹出元素
注:上溢是一种错误,使问题的处理无法进行;而下溢一般认为是一种结束条件,即问题处理结束。 |
3.3顺序栈的表示
(1)判断是否会栈空,若空则会出错(下溢);
(2)获取栈顶元素e;
(3)栈顶指针减1。
Status Pop(Sqstatus &S,SElemType &e){
//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;
否则返回ERROR
if(S.top==S.base) //等价于if(StackEmpty(S))
return ERROR;
e=*--S.top; //--S.top; e=*S.top;
return OK;
}栈空,(top==base)
4.链栈的表示和实现
4.1链栈的表示
链栈是运算受限的单链表,只能在链表头部进行操作
链表的特点:
|
注意:链栈中指针的方向 |
4.2链栈的入栈
Status Push(LinkStack &S,SElemType e){
p=new StackNode; //生成新结点p
p->data=e; //将新结点数据域置为e
p->next=S; //将新结点插入栈顶
S=p; //修改栈顶指针
return OK;
}4.3链栈的出栈
Status Pop(LinkStack &S,SElemType &e){
if(S==NULL)return ERROR;
e=S->data;
p=S;
S=S->next;
delete p;
return OK;
}4.4取栈顶元素
SElemType GetTop(LinkStack S){
if(S!=NULL)
return S->data;
}二、栈和递归
- 递归的定义
若一个对象部分地包含它自己,或用它自己给自己定义,则称这个对象是递归的;
若一个过程直接地或间接地调用自己,则称这个过程是递归的过程。
例如:递归求n的阶乘
long Fact(long n){
if(n==0)return 1;
else return n*Fact(n-1);
}以下三种情况常常用到递归方法:
递归定义的数学函数
具有递归特性的数据结构
可递归求解的问题
- 递归问题——用分治法求解
2.1分治法
分治法:对于一个较为复杂的问题,能够分解成几个相对简单的且解法相同或类似的子问题来求解 |
2.2必备的三个条件
能将一个问题转变成一个新问题,而新问题与原问题的解法相同或类同,不同的仅是处理的对象,且这些处理对象是变化有规律的;
可以通过上述转化而使问题简化;
必须一个明确的递归出口,或称递归的边界。
2.3分治法求解递归问题算法的一般形式
void p(参数表){
if (递归结束条件)可直接求解步骤;——基本项
else p(较小的参数);——归纳项例如:
long Fact(long n){
if(n==0)return 1; //基本项
else return n*Fact(n-1) //归纳项
}2.4函数调用过程
调用前,系统完成:
将实参返回地址等传递给被调用函数;
为被调用函数的局部变量分配存储区;
将控制转移到被调用函数的入口。
调用后,系统完成:
保存被调用函数简单计算结果;
释放被调用函数的数据区;
依照被调用函数保存的返回地址将控制转移到调用函数。

1488

被折叠的 条评论
为什么被折叠?



