当前位置: 首页 > news >正文

数据结构 05 栈和队列

1 栈只在一端(栈顶)进行运算,并非两端 

栈是只允许在表的一端(栈顶)进行插入和删除操作的线性表;队列是只允许在表的一端(队尾)进行插入操作,在另一端(队头)进行删除操作的线性表。

所以栈只在一端(栈顶)进行运算,并非两端。

2 循环队列不是以链表指针的方式来实现头尾相接

循环队列的典型实现是基于数组的,通过对数组下标进行特定的运算(如取模)来实现队列的头尾相接,从而重复利用数组空间。

虽然从广义的 “指针” 概念(比如数组下标也可看作一种地址标识),但通常我们所说的用 “指针” 实现,更多是指像链表那样用指针变量来链接节点。

而循环队列一般不用这种链表指针的方式来实现头尾相接,所以这一说法错误,答案选 “×”。

3 队列只允许在一端(队尾)进行插入(增加)操作,在另一端(队头)进行删除(减少)操作

队列是一种 “先进先出”(FIFO)的线性表,只允许在一端(队尾)进行插入(增加)操作,在另一端(队头)进行删除(减少)操作,并非下端和上端既能增加又能减少。

4 当有 n 个元素依次进栈时,合法的出栈序列数目恰好是第 n 个卡特兰数。

5 在单链表表示的链式队列里,队头位于链表的链头位置

队列是 “先进先出” 的线性结构,链式队列中,队头元素是最先进入队列的,在单链表表示的链式队列里,队头位于链表的链头位置,这样出队(删除队头元素)操作可以直接从链头进行,方便高效;而队尾位于链尾,用于入队操作。所以用单链表表示的链式队列的队头在链表的链头位置。

6 只有尾指针的循环链队列的入队和出队

以下是用 C 语言实现只有尾指针的循环链队列的入队和出队操作:

#include <stdio.h>
#include <stdlib.h>// 定义队列节点结构
typedef struct Node {int data;struct Node *next;
} Node;// 入队操作
void enQueue(Node **rear, int value) {// 创建新节点Node *newNode = (Node *)malloc(sizeof(Node));if (newNode == NULL) {printf("内存分配失败\n");exit(1);}newNode->data = value;// 如果队列为空if (*rear == NULL) {*rear = newNode;newNode->next = newNode; // 自己指向自己,形成循环} else {// 新节点的 next 指向原队头(尾指针的 next 指向队头)newNode->next = (*rear)->next;// 尾节点的 next 指向新节点(*rear)->next = newNode;// 尾指针后移到新节点*rear = newNode;}
}// 出队操作
int deQueue(Node **rear) {// 队列为空的情况if (*rear == NULL) {printf("队列为空,无法出队\n");exit(1);}Node *front = (*rear)->next; // 队头节点int data = front->data;// 如果队列中只有一个节点if (front == *rear) {*rear = NULL;} else {// 尾指针的 next 指向原队头的下一个节点,即新的队头(*rear)->next = front->next;}free(front);return data;
}// 测试函数
int main() {Node *rear = NULL;// 入队enQueue(&rear, 1);enQueue(&rear, 2);enQueue(&rear, 3);// 出队并打印printf("出队元素: %d\n", deQueue(&rear));printf("出队元素: %d\n", deQueue(&rear));printf("出队元素: %d\n", deQueue(&rear));// 再次入队测试enQueue(&rear, 4);printf("出队元素: %d\n", deQueue(&rear));return 0;
}

代码说明

  1. 入队操作(enQueue
    • 首先创建新节点存储要入队的数据。
    • 如果队列为空(尾指针 rear 为 NULL),则新节点的 next 指向自身,尾指针指向新节点,形成只有一个节点的循环队列。
    • 如果队列不为空,新节点的 next 指向原队头(尾指针的 next 指向队头),然后尾节点的 next 指向新节点,最后尾指针后移到新节点。
  2. 出队操作(deQueue
    • 先判断队列是否为空,为空则无法出队。
    • 找到队头节点(尾指针的 next 指向队头),保存队头节点的数据。
    • 如果队列中只有一个节点,出队后队列为空,尾指针置为 NULL
    • 否则,尾指针的 next 指向原队头的下一个节点(即新的队头),然后释放原队头节点的内存,返回其数据。
  3. 测试部分:在 main 函数中进行入队和出队操作的测试,验证代码的正确性。

7 实现两个共享存储区、栈顶相向增长的顺序栈的入栈和出栈

1. 定义栈结构

#define maxsize 100 // 假设最大容量为 100
typedef struct {int data[maxsize]; // 共享的存储数组int top1; // 栈 S1 的栈顶指针,初始为 -1int top2; // 栈 S2 的栈顶指针,初始为 maxsize
} DoubleStack;

2. 入栈操作

// 入栈操作,stack 为双栈,x 为入栈元素,stackNum 为栈编号(1 表示 S1,2 表示 S2)
int push(DoubleStack *stack, int x, int stackNum) {// 检查是否栈满(两个栈顶指针相邻,说明空间用尽)if (stack->top1 + 1 == stack->top2) {printf("栈满,无法入栈\n");return 0;}if (stackNum == 1) {// S1 入栈,栈顶指针上移,元素放入对应位置stack->data[++(stack->top1)] = x;} else if (stackNum == 2) {// S2 入栈,栈顶指针下移,元素放入对应位置stack->data[--(stack->top2)] = x;} else {printf("栈编号错误\n");return 0;}return 1;
}

3. 出栈操作

// 出栈操作,stack 为双栈,x 用于存储出栈元素,stackNum 为栈编号(1 表示 S1,2 表示 S2)
int pop(DoubleStack *stack, int *x, int stackNum) {if (stackNum == 1) {// 检查 S1 是否为空if (stack->top1 == -1) {printf("S1 栈空,无法出栈\n");return 0;}// S1 出栈,栈顶指针下移,取出元素*x = stack->data[stack->top1--];} else if (stackNum == 2) {// 检查 S2 是否为空if (stack->top2 == maxsize) {printf("S2 栈空,无法出栈\n");return 0;}// S2 出栈,栈顶指针上移,取出元素*x = stack->data[stack->top2++];} else {printf("栈编号错误\n");return 0;}return 1;
}

简单解释

  • 入栈:两个栈 S1 和 S2 栈顶相向,S1 栈顶从存储区起始位置(top1 初始为 -1)向上增长,S2 栈顶从存储区末尾位置(top2 初始为 maxsize)向下增长。入栈时先判断是否栈满(top1 + 1 == top2 表示空间用尽),若不满则根据栈编号,调整对应栈顶指针并放入元素。
  • 出栈:出栈时先判断对应栈是否为空,若不为空则根据栈编号,调整对应栈顶指针并取出元素。
http://www.dtcms.com/a/482068.html

相关文章:

  • 01、大模型部署方案与Dify的使用
  • 使用Spring Boot构建消息通信层
  • 山东济南seo整站优化公司对其网站建设进行了考察调研
  • MIPI_CSI22_Xilinx IP
  • 【C++STL :stack queue (一) 】STL:stack与queue全解析|深入使用(附高频算法题详解)
  • DevOps工具链对比,云效 vs TikLab哪一款更好用?
  • Kanass,一款超级轻量且简洁的项目管理工具
  • 如何做企业的网站微信如何开通小程序
  • 【从0开始学习Java | 第20篇】网络编程
  • PetaLinux 工程迁移指南
  • Java面试实战:互联网医疗场景中的JVM调优与Spring Boot应用
  • http环境实现通知
  • 分布式雷达 vs 多基地雷达:同频共振的“合唱团”和“乐队”
  • 手机端-adb脚本自动化-真机版
  • Python爬虫常见陷阱:Ajax动态生成内容的URL去重与数据拼接
  • 简繁英3合1企业网站生成管理系统V1.6wordpress如何降级
  • 【学以致用|python自动化办公】OCR批量识别自动存为Excel(批量识别发票)
  • AJAX 实时搜索
  • 详细介绍C++中通过OLE操作excel时,一般会出现哪些异常,这些异常的原因是什么,如何来解决这些异常
  • ES6知识点详解和应用场景
  • 网站平台建设可行性c 网站开发项目教程
  • Webpack 核心知识点详解:proxy、热更新、Loader与Plugin全解析
  • 本地搭建 Jekyll 环境
  • 前端基础之《React(1)—webpack简介》
  • 攻击者利用Discord Webhook通过npm、PyPI和Ruby软件包构建隐蔽C2通道
  • [Spark] Metrics收集流程
  • pyspark并行性能提升经验
  • HTML盒子模型详解
  • 个人电脑做网站违法吗东莞市住建局官网
  • 下载selenium-ide及使用