【数据结构知识点总结】三、栈和队列

本文详细介绍了数据结构中的栈和队列。栈是一种后进先出(LIFO)的数据结构,包括顺序栈和链栈,讨论了它们的基本操作和共享栈的概念。队列则是先进先出(FIFO)的数据结构,涵盖顺序存储和链式存储,包括循环队列和双端队列,同时讲解了它们在函数调用、中缀表达式转换等方面的应用。此外,还探讨了特殊矩阵的压缩存储策略。
摘要由CSDN通过智能技术生成

栈(Stack)是一种线性表,只允许在一端进行插入或删除操作。特性:后进先出(LIFO)。

顺序栈

采用顺序存储的栈称为顺序栈。

#define MaxSize 50
typedef struct SqStack{
   
	ElemType data[MaxSize];
	int top;  //栈顶指针
}SqStack;

栈顶指针:S.top,初始时设置S.top=-1;
进栈操作:栈不满时,栈顶指针先加1,再送值到栈顶元素
出栈操作:栈非空时,先取栈顶元素值,再将栈顶指针减1
栈空条件:S.top==-1;
栈满条件:S.top==MaxSize-1;
栈长:S.top+1

基本操作

(1)初始化

void InitStack(SqStack &S){
   
	S.top=-1; //初始化栈顶指针
}

(2)判栈空

bool StackEmpty(SqStack S){
   
	if(S.top==-1){
   
		return true; //栈空
	}
	else{
   
		return false;
	}
}

(3)进栈

bool Push(SqStack &S,ElemType x){
   
    if(S.top==MaxSize-1){
   
        return false;
    }
    S.data[++S.top]=x; //指针先加1,再入栈
    return true;
}

(4)出栈

bool Pop(SqStack &S,ElemType &x){
   
    if(S.top==-1){
   
        return false;
    }
    x=S.data[S.top--]; //先出栈,指针再减1
    return true;
}

(5)读栈顶元素

bool GetTop(SqStack S,ElemType &x){
   
    if(S.top==-1){
   
        return fasle;
    }
    x=S.data[S.top];
    return true;
}
共享栈

可以让两个顺序栈共享一个一维数据空间,将两个栈的栈底分别设置在共享空间的两端,两个栈顶向共享空间的中间延伸。
在这里插入图片描述

链栈

优点:便于多个栈共享存储空间和提高其效率,且不存在栈满上溢的情况。

链栈没有头结点,Lhead指向栈顶元素。

typedef struct Linknode{
   
	ElemType data;
	struct Linknode *next;
}*LiStack;
练习

1.假设以I和O分别表示入栈和出栈操作。栈的初态和终态均为空,入栈和出栈的操作序列可表示为仅由I和O组成的序列,可以操作的序列称为合法序列,否则称为非法序列。
写出一个算法,判定所给的操作序列是否合法。若合法返回true,否则返回false

 bool Judge(char A[]){
   
    int j=0;
    int i=0, o=0;
    while(A[i]!='\0'){
     //未到字符数组尾
        switch(A[i]){
   
            case 'I':i++;
                break;
            case 'O':o++;
                if(o>i){
     //序列非法,退出
                    exit(0);
                }
        }
        i++;
    }
    if(i!=o){
   
        return false;
    }
    else{
   
        return true;
    }
}

2.设单链表的表头指针为L,结点结构由data和next两个域构成,其中data域为字符型。试设计算法判断该链表的全部n个字符是否中心对称。例如xyx、xyyx。

bool Symmetry(LinkList L,int n){
   
    int i;
    char s[n/2]; //字符栈
    p=L->next;
    for(i=0;i<n/2;i++){
   
        s[i]=p->data;
        p=p->next;
    }
    i--;
    if(n%2==1){
    //n是奇数
        p=p->next;
    }
    while(p!=NULL&&s[i]==p->data){
   
        i--;
        p=p->next;
    }
    if(i==-1){
   
        return true;
    }
    else{
   
        return false;
    }
}

队列

队列(queue)。简称队,只允许在表的一端进行插入,另一端进行删除。操作特性:先进先出(FIFO)
队头(front)。允许删除的一端,又称队首。
队尾(rear)。允许插入的一端。

顺序存储

分配一块连续的存储单元存放队列中的元素,并附设两个指针front和rear分别指向队头和队尾元素的位置。(也可以让front指向队头元素的前一个位置)

#define MaxSize 50  //定义队列元素的最大个数
typedef struct SqQueue{
   
	ElemType data[MaxSize];
	int front,rear;
}SqQueue;
循环队列

把存储队列元素的表从逻辑上视为一个环。当队首指针Q.front=MaxSize-1后,再前进一个位置就自动到0,可以利用除法取余运算(%)来实现。
初始:Q.front=Q.rear=0
队首指针进1:Q.front=(Q.front+1)%MaxSize
队尾指针进1:Q.front=(Q.rear+1)%MaxSize
队列长度:(Q.rear+MaxSize-Q.front)%MaxSize

判断队空和队满:

  1. 牺牲一个单元来区分队空和队满
    在这里插入图片描述
    队满条件:(Q.rear+1)%MaxSize==Q.front
    队空条件:Q.rear==Q.front

  2. 增加表示元素个数的数据成员。
    队空条件:Q.size==0
    队满条件:Q.size==MaxSize

  3. 增加tag数据成员。tag等于0时,若因删除导致Q.front==Q.rear,则队空;tag等于1时,若因插入导致Q.front=

  • 0
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

叶柖

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

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

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

打赏作者

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

抵扣说明:

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

余额充值