学习笔记:第三章 栈与队列

第三章 栈与队列

第一部分 栈

1. 栈的定义

栈(stack)是限定仅在表尾进行插入和删除操作的线性表。

我们把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈。

栈又称为后进先出的线性表,简称LIFO结构。

栈的插入操作,叫作进栈,也称压栈。栈的删除操作,叫作出栈,有的也叫做弹栈。

在这里插入图片描述

2. 栈的抽象数据类型

ADT 栈(stack)
Data 
    同线性表。元素具有相同的类型,相邻元素具有前驱和后继关系。
Operation
    InitStack(&S): 初始化操作,建立一个空栈s。
    DestroyStack(&S): 若栈存在,则销毁它。
    ClearStack(&S): 将栈清空。
    StatckEmpty(S): 若栈存在且非空,返回true,否则返回false。
    GetTop(S,&e): 若栈存在且非空,用e返回S的栈顶元素。
    Push(&S,e): 若栈S存在,插入新元素e到栈S中并成为其栈顶对象。
    Pop(&S,&e): 删除栈S中的栈顶元素,并用e返回其值。
    StackLength(S): 返回栈S的元素个数。
    StackTraverse(S,visit()): 栈S已存在且非空。从栈底到栈顶依次对S的每个数据元素调用visit()。
endADT

3. 栈的顺序存储结构及实现

顺序栈,即栈的顺序存储结构是利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针top指示栈顶元素再顺序栈中的位置。(top=0表示空栈)。

首先,先为栈分配一个基本容量,然后在应用的过程中,当栈的空间不够使用时再逐段扩大。为此,设定两个常量:STACK_INIT_SIZE (存储空间初始分配量) 和 STACKINCREMENT (存储空间分配增量)。

(一)栈的定义方式:

typedef struct{
	SElemtype *base;  //栈底指针
	SElemtype *top;   //栈顶指针
    int stacksize;    //当前可使用的最大容量
}SqStack;

在这里插入图片描述

(1)栈的初始化:
Status InitStack(SqStack &S){
	S.base=(SElemtype *)malloc(STACK_INIT_SIZE*sizeof(SElemtype));
	if(!S.base)     //如果base的值为空,则表明结构体不存在
		return(OVERFLOW);
	S.top=S.base;   //(top=base 可作为栈为空的标记)
	S.stacksize=STACK_INIT_SIZE;   //按照初始分配量进行第一次存储分配
	return OK;
}
(2)栈的销毁:
Status DestoryStack(SqStack &S)
{
	free(S.base);
	S.base = NULL;
	S.top = NULL;
	S.stacksize = 0;
	return OK;
}
(3)栈的清空:
Status ClearStack(SqStack &S)
{
	S.top = S.base;
	return OK;
}
(4)判断栈是否为空:
Status StackEmpty(SqStack S)
{
	if(S.top == S.base)
		return TRUE;
	else
		return FALSE;
}
(5)返回栈顶元素:
Status GetTop(SqStack S,SElemType &e)
{
	if(S.top == S.base) 
        return ERROR;
	e = *(S.top -1);
	return OK;
}
(6)压栈:
Status Push(SqStack &S, SElemType e)
{
	if(S.top - S.base >= S.stacksize)  //栈满,追加存储空间
	{
		S.base = (SElemType *)realloc(S.base,(S.stacksize + STACKINCREMENT)*sizeof(SElemType));
		if(!S.base) 
            exit(OVERFLOW);
		S.top = S.base + S.stacksize;
		S.stacksize += STACKINCREMENT; 
	}
	*S.top++ = e;
	return OK;
}
(6)出栈:
Status Pop(SqStack &S, SElemType &e)
{
	if(S.top == S.base) return ERROR;
	e = * --S.top;
	return OK;
}
(7)栈的元素个数:
int StackLength(SqStack S)
{
	return S.top - S.base;
}
(8)栈元素从栈底依次输出:
Status StackTraverse(SqStack S, Status(* visit)(SElemType))
{
	while(S.top > S.base)
		visit(*S.base++);
	printf("\n");
	return OK;
}

Status visit(SElemType e)
{
	printf("%d ", e);
	return OK;
}

(二)栈的另一种方式定义方式:

typedef struct
{
        SElemType data[MAXSIZE];
        int top; // 用于栈顶指针 
}SqStack;
(1)栈的初始化:
Status InitStack(SqStack &S)
{ 
        /* S.data=(SElemType *)malloc(MAXSIZE*sizeof(SElemType)); */
        S.top=-1;
        return OK;
}
(2)栈的清空:
Status ClearStack(SqStack &S)
{ 
        S.top=-1;
        return OK;
}
(3)判断栈是否为空:
Status StackEmpty(SqStack S)
{ 
        if (S.top==-1)
                return TRUE;
        else
                return FALSE;
}
(4)返回栈顶元素:
Status GetTop(SqStack S,SElemType &e)
{
        if (S.top==-1)
                return ERROR;
        else
                e=S.data[S.top];
        return OK;
}
(5)压栈:
Status Push(SqStack &S,SElemType e)
{
        if(S.top == MAXSIZE -1) 
        {
                return ERROR;
        }
        S.top++;				//栈顶指针增加一 
        S.data[S.top]=e;  //将新插入元素赋值给栈顶空间
        return OK;
}
(6)出栈:
Status Pop(SqStack &S,SElemType &e)
{ 
        if(S.top==-1)
                return ERROR;
        e=S.data[S.top];	
        S.top--;			
        return OK;
}
(7)栈的元素个数:
int StackLength(SqStack S)
{ 
        return S.top+1;
}
(8)栈元素从栈底依次输出:
Status visit(SElemType c)
{
        printf("%d ",c);
        return OK;
}

Status StackTraverse(SqStack S)
{
        int i;
        i=0;
        while(i<=S.top)
        {
                visit(S.data[i++]);
        }
        printf("\n");
        return OK;
}

4. 两栈共享空间

将一个栈的栈底为数组的始端,即下标为0处。另一个栈为数组的末端,即下标为数组长度n-1处。
两个栈如果增加元素,就是两端点向中间延伸。

在这里插入图片描述

typedef struct 
{
        SElemType data[MAXSIZE];
        int top1;	//栈1栈顶指针
        int top2;	//栈2栈顶指针
}SqDoubleStack;
(1) 栈的初始化:
Status InitStack(SqDoubleStack &S)
{ 
        S.top1=-1;
        S.top2=MAXSIZE;
        return OK;
}
(2) 栈的清空:
Status ClearStack(SqDoubleStack &S)
{ 
        S.top1=-1;
        S.top2=MAXSIZE;
        return OK;
}
(3) 判断栈是否为空:
Status StackEmpty(SqDoubleStack S)
{ 
        if (S.top1==-1 && S.top2==MAXSIZE)
                return TRUE;
        else
                return FALSE;
}
(4) 压栈:
//插入元素e为新的栈顶元素
Status Push(SqDoubleStack &S,SElemType e,int stackNumber)
{
        if (S.top1+1==S.top2)	// 栈满
                return ERROR;	
        if (stackNumber==1)			//栈1有元素进栈
                S.data[++S.top1]=e; 
        else if (stackNumber==2)	//栈2有元素进栈
                S.data[--S.top2]=e; 
        return OK;
}
(5) 出栈:
Status Pop(SqDoubleStack &S,SElemType &e,int stackNumber)
{ 
        if (stackNumber==1) 
        {
                if (S.top1==-1) 
                        return ERROR;
                e=S.data[S.top1--]; 
        }
        else if (stackNumber==2)
        { 
                if (S.top2==MAXSIZE) 
                        return ERROR; 
                e=S.data[S.top2++];
        }
        return OK;
}
(6) 栈的元素个数:
// 返回S的元素个数,即栈的长度
int StackLength(SqDoubleStack S)
{ 
        return (S.top1+1)+(MAXSIZE-S.top2);
}
(7) 栈元素从栈底依次输出:
Status visit(SElemType c)
{
        printf("%d ",c);
        return OK;
}

Status StackTraverse(SqDoubleStack S)
{
        int i;
        i=0;
        while(i<=S.top1)
        {
                visit(S.data[i++]);
        }
        i=S.top2;
        while(i<MAXSIZE)
        {
                visit(S.data[i++]);
        }
        printf("\n");
        return OK;
}

5. 栈的链式存储结构及实现

在这里插入图片描述

typedef struct StackNode
{
        SElemType data;
        struct StackNode *next;
}StackNode,*LinkStackPtr;


typedef struct
{
        LinkStackPtr top;
        int count;
}LinkStack;
(1) 栈的初始化:
Status InitStack(LinkStack &S)
{ 
        S.top = (LinkStackPtr)malloc(sizeof(StackNode));
        if(!S.top)
                return ERROR;
        S.top=NULL;
        S.count=0;
        return OK;
}
(2) 栈的清空:
//把S置为空栈
Status ClearStack(LinkStack &S)
{ 
        LinkStackPtr p,q;
        p=S.top;
        while(p)
        {  
                q=p;
                p=p->next;
                free(q);
        } 
        S.count=0;
        return OK;
}
(3) 判断栈是否为空:
//若栈S为空栈,则返回TRUE,否则返回FALSE
Status StackEmpty(LinkStack S)
{ 
        if (S.count==0)
                return TRUE;
        else
                return FALSE;
}
(4) 返回栈顶元素:
Status GetTop(LinkStack S,SElemType &e)
{
        if (S.top==NULL)
                return ERROR;
        else
                e=S.top->data;
        return OK;
}
(5) 压栈:
Status Push(LinkStack &S,SElemType e)
{
        LinkStackPtr s=(LinkStackPtr)malloc(sizeof(StackNode)); 
        s->data=e; 
        s->next=S.top;	// 把当前的栈顶元素赋值给新结点的直接后继。
        S.top=s;        // 将新的结点s赋值给栈顶指针
        S.count++;
        return OK;
}
(6) 出栈:
Status Pop(LinkStack &S,SElemType &e)
{ 
        LinkStackPtr p;
        if(StackEmpty(S))
                return ERROR;
        e=S.top->data;
        p=S.top;					//将栈顶结点赋值给p。
        S.top=S.top->next;    		//使得栈顶指针下移一位,指向后一结点。
        free(p);                        
        S.count--;
        return OK;
}
(7) 栈的元素个数:
int StackLength(LinkStack S)
{ 
        return S.count;
}
(8) 栈元素依次输出:
Status visit(SElemType c)
{
        printf("%d ",c);
        return OK;
}

Status StackTraverse(LinkStack S)
{
        LinkStackPtr p;
        p=S.top;
        while(p)
        {
                 visit(p->data);
                 p=p->next;
        }
        printf("\n");
        return OK;
}

在这里插入图片描述
但行好事,莫问前程。
不忘初心,方得始终。
做好自己,温暖且积极!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序猿小张的日常笔记

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

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

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

打赏作者

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

抵扣说明:

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

余额充值