数据结构与算法——第三章 栈和队列(2)

目录

3.3 栈的表示和操作的实现 

3.3.1 栈的抽象数据类型的类型定义

3.3.2 顺序栈的表示和实现

顺序栈算法基本操作:

1. 顺序栈的初始化

2. 顺序栈判断栈是否为空

3. 求顺序栈长度

4. 清空顺序栈

5. 销毁顺序栈

6. 顺序栈的入栈

7. 顺序栈的出栈

3.3.3 链栈的表示和实现

1. 链栈的表示

2. 链栈的初始化

3. 判断链栈是否为空

4. 链栈的入栈

5. 链栈的出栈

6. 取栈顶元素

3.4 栈与递归

3.4.1 递归的定义

3.4.2 递归问题——用分治法求解 

3.4.3 递归优缺点

3.4.4 借助栈改写递归

3.3 栈的表示和操作的实现 

3.3.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 Stack

InitStack(&s)        初始化操作

操作结果:构造一个空栈S。

DestoryStack(&S)        销毁栈操作

初始条件:栈S已存在。

操作结果:栈S被销毁。

StackEmpty(S)        判定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返回其值。

3.3.2 顺序栈的表示和实现

1. 示范

2. 栈满时的处理方法

1、报错,返回操作系统。

2、分配更大的空间,作为栈的存储空间,将原栈的内容移入新栈。

3. 数组作为顺序栈存储方式

4. 顺序栈的表示

# define MAXSIZE 100
typedef struct{
    SElemType *base;    // 栈底指针
    SElemType *top;     // 栈顶指针
    int stacksize;      // 栈可用最大容量
}SqStack;

注:top和base可以定义为int,用来放下标,要相减必须指向同一数组。

顺序栈算法基本操作:

 

1. 顺序栈的初始化

Status InitStack(SqStack &S){    // 构造一个空栈
    S.base = new SElemType[MAXSIZE];    // c++语法中new后面跟类型, 或
 // S.base = (SElemType*)malloc(MAXSIZE*sizeof(SElemType));    // c语法
    // 分配MAXSIZE空间的SElemType类型,malloc:动态分配函数,转换成SElemType类型指针
    if (!S.base)    
        exit(OVERFLOW);    // 存储分配失败
    S.top = S.base;        // 栈顶指针等于栈底指针
    S.stacksize = MAXSIZE;
    return OK;
}

2. 顺序栈判断栈是否为空

Status StackEmpty(SqStack S){   
    // 若栈为空,返回TRUE;否则返回FALSE
    if(S.top == S.base)
        return TRUE;
    else
        return FALSE;
}

3. 求顺序栈长度

int StackLength( SqStack S )
{
    return S.top-S.base;
}

4. 清空顺序栈

Status ClearStack( SqStack S ){
    if( S.base )    // 如果这个栈存在
        S.top = S.base;
    return OK;
}

5. 销毁顺序栈

Status DestoryStack( SqStack &S){
    if( S.base )
    {
        delete S.base;
        S.stacksize = 0;
        S.base = S.top = NULL;
    }
    return OK;
}

6. 顺序栈的入栈

(1)判断是否栈满,若满则出错(上溢)

(2)元素e压入栈顶

(3) 栈顶指针加1

Status Push( SqStack &S, SElemType e){
    if( S.top-S.base == S.stacksize )    // 栈满
        return ERROR;
    *S.top ++= e;    // *S.top=e;  S.top++;
    return OK;
}

7. 顺序栈的出栈

(1)判断是否栈空,若空则出错(下溢)

(2)获取栈顶元素e

(3)栈顶指针减1

Status Pop(SaStack &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;
}

3.3.3 链栈的表示和实现

1. 链栈的表示

        链栈运算受限的单链表,只能在链表头部进行操作。

typedef struct StackNode{
    SElemType data;
    struct StackNode *next;
} StackNode, *LinkStack;
LinkStack S;

2. 链栈的初始化

void InitStack(LinkStack &S){
    // 构造一个空栈,栈顶指针置为空
    S = NULL;
    return OK;
}

3. 判断链栈是否为空

Status StackEmpty(LinkStack S){
    if (S==NULL)
        return ERROR;
    else
        return FALSE;
}

4. 链栈的入栈

        加一p指针,给p的next域赋给头结点s地址,在将s存入p的地址,再将值赋给s。        

Status Push(LinkStack &S, SElemType e){
    p = new StackNode;    // 生成新结点p
    p -> data = e;        // 将新结点数据域置为e
    p -> next = S;        // 将新结点插入栈顶
    S = p;                // 修改栈顶指针
    return OK;
}

5. 链栈的出栈

        用新的元素e和指针p提取元素和指针,头结点指向next域的结点,释放p。

 

Status Pop(LinkStack &S, SElemType &e){
    if(S==NULL)
        return ERROR;
    e = S -> data;
    p = S;
    S = S -> next;
    delete p;
    return OK;
}

6. 取栈顶元素

SElemType GetTop(LinkStack S){
    if(S!=NULL)
        return S->data;
}

3.4 栈与递归

3.4.1 递归的定义

(1)若一个对象部分地包含它自己,或用它自己给自己定义,则称这个对象是递归的;

(2)若一个过程直接地或间接地调用自己,则称这个过程是递归的过程。

        e.g. 递归求n的阶乘

long Fact( long n ){
    if( n == 0 )
        return 1;
    else
        return n * Fact(n-1);
}

        

 (1)

 (2)

(3)

3.4.2 递归问题——用分治法求解 

3.4.3 递归优缺点

 (1)

(2) 

3.4.4 借助栈改写递归

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清园暖歌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值