数据结构 - 栈和队列 知识点

数据结构 - 栈和队列

  1. 线性表
    • 操作受限
      • 栈: 顺序栈,链栈,共享栈
      • 队列: 循环队列,链式队列,双端队列
    • 推广
      • 数组: 一维数组 ,多维数组 ,压缩存储,稀疏矩阵

1. 栈

  1. 栈是只允许在一端进行插入和删除的线性表;首先栈是一种线性表,后进先出(LIFO)
  2. 数学性质: n个不同元素进栈,出栈元素不同排列个数为(1/n+1)*C(n,2n) 又称卡特兰数
1.1 顺序栈
  1. 采用顺序存储的栈成为顺序栈,利用一组地址连续的存储单元存放自栈底到栈顶的数据元素,并附设栈顶指针(top)指示当时栈顶元素的位置
#define MaxSize 50
typedef struct{
    Elemtype data[MaxSize];
    int top;
}SqStack;
栈顶指针: S.top ,初始 S.top=-1,栈顶元素 S.data[S.top]
栈空 S.top =-1  栈满 S.top = MaxSize-1 栈长 S.top+1

//初始化
void InitStack(SqStack &S){
    S.top = -1;
}
// 判栈空
bool StackEmpty(SqStack S){
    if(S.top == -1) return true;
    else return false;
}
//进栈
bool Push(SqStack &S,Elemtype value){
    if(S.top!=MaxSize-1){
        S.top++;
        S.data[S.top] = value;
        return true;
    }
    else return false;
}
//出栈
bool Pop(SqStack &S,Elemtype &value){
    if(S.top != -1){
        value = S.data[S.top];
        S.top--;
        return true; 
    }
    else return false;
}
//获取栈顶元素
bool GetTop(SqStack S,Elemtype &value){
    if(S.top != -1){
        value=S.data[S.top];
        return true;
    }
    return false;
}

2. 队列

  1. 只允许在一端进行插入,另一端进行删除,简称 入队,和 出队 先进先出(FIFO)
  2. 队头: Front 允许删除 ; 队尾: Rear 允许插入
  3. 队列顺序存储是分配一块连续的存储单元存放队列元素,并附设 队头和队尾指针
#define MaxSize 50
typedef struct{
    ElemType data[MaxSize];
    int front,rear;
}SqQueue;

初始(队空): Q.front = Q.rear = 0;

2.1 循环队列
  1. 将顺序队列想象成一个环状空间,即把队列元素从逻辑上视为一个环,成为 循环队列

    初始: Q.front = Q.rear = 0;
    队首指针进1: Q.front = (Q.front+1)%MaxSize;
    队尾指针进1: Q.rear = (Q.rear+1)%MaxSize;
    队列长度: (Q.rear+MaxSize-Q.front)%MaxSize;
    出队入队时,指针 按顺时针方向进1
    队满: (Q.rear+1)%MaxSize = Q.front;
    队空: Q.front = Q.rear;

https://img-blog.csdnimg.cn/img_convert/6a56e74e434b11c299a072e1a89b2b24.png
2. 循环队列操作

// initation
void InitQueue(SqQueue &Q){
    Q.front = Q.rear = 0;
}

//empty
bool empty(SqQueue &Q){
    if((Q.rear+1)%MaxSize == Q.front) return true;
    return false;
}
// enQueue
bool enQueue(SqQueue &Q, ElemType k){
    if((Q.rear+1)%MaxSize == Q.front) return false;
    Q.data[Q.rear]= k;
    Q.rear = (Q.rear+1)%MaxSize;
    return true;
}
//deQueue
bool deQueue(SqQueue &Q, ElemType &k){
    if(Q.front == Q.rear) return false;
    k = Q.data[Q.front];
    Q.front = (Q.front+1)%MaxSize;
    return true;
}
2.2 链式队列
  1. 队列的链式表示为链队列,实际上是一个同时有队头指针和队尾指针的单链表
    https://img-blog.csdnimg.cn/img_convert/2e201e3ac52e9851826e196539ccd28f.png
typedef struct{
    ElemType data;
    struct LinkNode *next;
}LinkNode;
typedef struct{
    LinkNode *front,*rear;
}LinkQueue;

//init
void InitQueue(LinkQueue &Q){
    Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode));
    Q.front->next = NULL;
}
//isempty
bool isEmpty(LinkQueue  &Q){
    if(Q.front == Q.rear) return true;
    return false;
}
//enQueue
void enQueue(LinkQueue &Q,ElemType k){
    LinkNode *s = (LinkNode*)malloc(sizeof(LinkNode));
    s->data = k;
    s->next = NULL
    Q.rear->next = s;
    Q.rear = s;
    
}
//deQueue
bool deQueue(LinkQueue &Q,ElemType &k){
    if(Q.front == Q.rear) return false;
    LinkNode *p = Q.front->next;
    k = p->data;
    Q.front->next = p->next;
    if(Q.rear == p) Q.front = Q.rear;   //若原队列只有一个节点,出队以后变空
    free(p);
    return true;
}
<think>嗯,用户想了解数据结构中的队列的基本概念与操作。首先,我需要回忆一下队列的定义特点。是后进先出的结构,而队列是先进先出。两者的操作有哪些不同呢?的pushpop在顶进行,队列的enqueue在队尾,dequeue在队头。 接下来,我应该分点讲解队列的基本概念,然后分别介绍它们的存储结构,比如顺序、链式,顺序队列(循环队列链式队列。需要提到它们的实现方式关键操作,比如入出栈,入队、出队。同时,要结合用户提供的引用内容,引用中有提到队列的实现类似于动态顺序表单链表,可以引用这些内容来说明实现原理。 用户的问题可能还涉及应用场景,比如在函数调用中的应用,队列在任务调度中的使用。另外,用户提供的引用里提到了循环队列的frontrear指针,以及双端队列的内容,这些可能需要简要提及,但用户当前的问题集中在基本概念与操作,所以可能不需要深入双端队列。 还要注意用户要求生成相关问题,所以最后要列出几个相关的问题,比如队列的区别、循环队列的实现原理、常见应用场景等。同时,确保回答结构清晰,使用中文,正确应用LaTeX格式,比如的操作时间复杂度是$O(1)$,队列的链式存储结构等。 需要检查是否有遗漏的关键点,比如队列的初始化、判空操作,顺序队列的假溢出问题如何通过循环队列解决。用户提供的引用中有类型声明,可以引用顺序队列的代码示例,比如SqQueue的结构体定义。同时,结合引用中的内容说明队列的实现基础,如动态顺序表链表,帮助用户理解。 最后,确保回答符合系统级指令,行内数学表达式用$...$,独立公式用$$...$$,正确使用引用标识,如[^1]、[^2]、[^3]。需要确认引用的内容是否与当前主题相关,比如引用[1]提到队列用已有数据结构实现,引用[2][3]详细讲解队列的结构操作,这些都可以在回答中引用以增强可信度。</think># 数据结构队列基本概念与操作详解 ## 一、(Stack) ### 1. 基本概念 - **定义**:后进先出(LIFO)的线性表,仅允许在表尾(称为顶)进行插入(push)删除(pop)操作[^1]。 - **核心操作**: -:$O(1)$时间复杂度,例如`push(5)` - 出栈:$O(1)$时间复杂度,例如`pop()` - 获取元素:$O(1)$时间复杂度 - 判空操作:$O(1)$时间复杂度 ### 2. 存储结构 - **顺序**: - 基于数组实现,需预分配连续内存空间 - 关键字段:顶指针`top` ```c #define MAX_SIZE 100 typedef struct { int data[MAX_SIZE]; int top; } SeqStack; ``` 引用顺序实现与动态顺序表类似[^1] - **链式**: - 基于链表实现,无需预分配空间 - 关键字段:头指针作为顶 ```c typedef struct Node { int data; struct Node *next; } LinkStack; ``` ## 二、队列(Queue) ### 1. 基本概念 - **定义**:先进先出(FIFO)的线性表,插入(enqueue)在队尾进行,删除(dequeue)在队头进行[^2] - **核心操作**: - 入队:$O(1)$时间复杂度 - 出队:$O(1)$时间复杂度 - 获取队头元素:$O(1)$时间复杂度 - 判空操作:$O(1)$时间复杂度 ### 2. 存储结构 - **顺序队列(循环队列)**: - 解决假溢出问题:通过模运算实现环形结构 - 队空条件:`front == rear` - 队满条件:`(rear+1)%MAX_SIZE == front` ```c typedef struct { ElemType data[MaxSize]; int front, rear; } SqQueue; // 引自引用[3] ``` - **链式队列**: - 包含头指针尾指针的单链表结构 ```c typedef struct QNode { int data; struct QNode *next; } QNode; typedef struct { QNode *front; QNode *rear; } LinkQueue; ``` ## 三、关键差异对比 | 特性 | | 队列 | |-----------|---------------------|---------------------| | 操作特性 | LIFO | FIFO | | 插入/删除位置 | 仅顶 | 队尾插入/队头删除 | | 典型应用场景 | 函数调用、表达式求值 | 任务调度、广度优先搜索 | | 空间利用率问题 | 顺序可能溢出 | 循环队列解决假溢出 | ## 四、应用场景解析 1. **的典型应用**: - 括号匹配检测:通过结构验证括号嵌套合法性 - 递归函数调用:系统保存函数调用现场 - 后缀表达式计算:运算符优先级处理 2. **队列的典型应用**: - 操作系统进程调度:维护就绪队列 - 打印任务管理:按提交顺序处理任务 - 消息队列:实现系统间异步通信
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值