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

栈与队列(c语言实现)

文章目录

  • 1.栈
    • 1.1基于数组实现栈
      • 1.1.1定义栈的结构体
      • 1.1.2栈的初始化
      • 1.1.3栈的释放
      • 1.1.4元素入栈
      • 1.1.5元素出栈
      • 1.1.6访问栈顶元素
    • 1.2基于链表实现栈
    • 1.2.1链表的结构体定义
      • 1.2.2初始化栈
      • 1.2.3销毁栈
      • 1.2.4元素出栈
      • 1.2.5访问栈顶元素
  • 2.队列
    • 2.1基于数组的队列
      • 2.1.1队列的结构体定义
      • 2.1.2队列的初始化
      • 2.1.3销毁队列
      • 2.1.4入队
      • 2.1.5访问队首元素
      • 2.1.6出队
    • 2.2基于链表的队列
      • 2.1.1队列结构体的定义
      • 2.1.2队列初始化
      • 2.1.3队列的删除
      • 2.1.4元素入队
      • 2.1.5访问队首元素
      • 2.1.6出队

栈就像叠猫猫,遵循"先入后出"的原则;队列就像猫猫排队,遵循”先入先出“的原则。栈和队列均可以通过数组(顺序表)和链表(链表)来实现。

1.栈

栈的主要操作可以分为以下几种:

方法描述时间复杂度
push()元素入栈(添加至栈顶)O(1)
pop()栈顶元素出栈O(1)
peek()访问栈顶元素O(1)

1.1基于数组实现栈

1.1.1定义栈的结构体

typedef int ElemType;  
typedef struct {  ElemType* data;  int length;  
}SqStack;

1.1.2栈的初始化

SqStack *InitStack() {  SqStack* stack = malloc(sizeof(SqStack));  stack->data = (ElemType*)malloc(sizeof(ElemType)*Max_Size);  stack->length = 0;  return stack;  
}

1.1.3栈的释放

//栈的释放  
void DestoryStack(SqStack* stack) {  free(stack->data);  free(stack);  
}

1.1.4元素入栈

void push(SqStack* stack,ElemType e) {  if(stack->length == Max_Size) {  printf("栈满!\n");  return;  }  stack->data[stack->length++] = e;  
}

stack->data[stack->length++] = e;:如果栈未满,将元素 e 存储在栈的当前位置(由 stack->length 指示),然后增加 stack->length 的值,表示栈中元素的数量增加了。

1.1.5元素出栈

 //元素出栈  
ElemType pop(SqStack* stack) {  if (stack->length == 0) {  printf("栈空!\n");  return -1;  }  return stack->data[stack->length--];  
}

1.1.6访问栈顶元素

//访问栈顶元素  
ElemType peek(SqStack* stack) {  if(stack->length == 0) {  printf("栈空!\n");  return -1;  }  return stack->data[stack->length-1];  
}

1.2基于链表实现栈

1.2.1链表的结构体定义

typedef int ElemType;  
//定义链表结构体  
typedef struct StackNode{  ElemType* data;  struct StackNode* next;  
}StackNode, *LinkStackPtr;  
//定义栈的结构体  
typedef struct {  StackNode* top;  int length;  
}LinkStack;

1.2.2初始化栈

//初始化栈  
LinkStack* InitStack() {  LinkStack* s = malloc(sizeof(LinkStack));  if (s == NULL) {  printf("内存分配失败!\n");  return NULL;  }  s->top = NULL;  s->length = 0;  return s;  
}

1.2.3销毁栈

//销毁栈  
void DestroyStack(LinkStack* s) {  //由栈顶到栈底,逐次释放  while (s->top) {  StackNode *n = s->top;  free(n);  s->top = s->top->next;  }  free(s);  
}

1.2.4元素出栈

//元素出栈  
ElemType pop(LinkStack* s) {  StackNode *node = malloc(sizeof(StackNode));  node->data = s->top->data;//将元素复制到node链表  StackNode *tmp = s->top;  s->top = s->top->next;//这里将top更新  free(tmp);  s->length--;return node->data;  
}

1.2.5访问栈顶元素

//访问栈顶元素  
ElemType peek(LinkStack* s) {  if(s->length == 0) {  printf("栈空");  return -1;  }  return s->top->data;  
}

2.队列

为了实现队列,我们需要一种数据结构,可以在一端添加元素,并在另一端删除元素,链表和数组都符合要求。

2.1基于数组的队列

2.1.1队列的结构体定义

//结构体定义  
typedef int ElemType;  
typedef struct {  ElemType* data;  ElemType front;     //队首指针  ElemType end;       //队尾指针  int length;     //队列长度  
}ArrayQueue;

2.1.2队列的初始化

//队列的初始化  
ArrayQueue *InitQueue(int queCapcity) {  ArrayQueue* queue = (ArrayQueue*)malloc(sizeof(ArrayQueue));  queue->length = queCapcity;  queue->front = queue->end = 0;  queue->data = (ElemType*)malloc(sizeof(ElemType)*queue->length);  return queue;  
}

2.1.3销毁队列

//销毁队列  
bool DestoryQueue(ArrayQueue* queue) {  free(queue->data);  free(queue);  return true;  
}

2.1.4入队

//入队  
void push(ArrayQueue* queue,ElemType e) {  if(queue->length == queue->end) {  printf("队满");  return;  }  int rear = (queue->front + queue->end) % queue->length;  queue->data[rear] = e;  queue->end++;  
}

2.1.5访问队首元素

//访问队首元素  
ElemType geek(ArrayQueue* queue) {  return queue->data[queue->front];  
}

2.1.6出队

//出队  
ElemType pop(ArrayQueue* queue) {  ElemType num = peek(queue);  queue->front = (queue->front + 1) % queue->length;  return num;  
}

2.2基于链表的队列

2.1.1队列结构体的定义

我们可以将链表的“头节点”和“尾节点”分别视为“队首”和“队尾”,规定队尾仅可添加节点,队首仅可删除节点。

typedef int ElumType;  
typedef struct Linklist{  ElumType* data;  struct Linklist* next;  
}LNode;  
typedef struct {  LNode *front,*rear;  int quelength;  
}LinkListQueue;

2.1.2队列初始化

//队列的初始化  
LinkListQueue* InitLinkListQueue() {  LinkListQueue* queue = (LinkListQueue*)malloc(sizeof(LinkListQueue));  queue->front = NULL;  queue->rear = NULL;  queue->quelength = 0;  return queue;  
}

2.1.3队列的删除

//队列的删除  
void DestroyLinkListQueue(LinkListQueue *queue) {  while (queue->front != NULL) {  LNode* temp = queue->front;  queue->front = queue->front->next;  free(temp);  }  free(queue);  
}

2.1.4元素入队

//入队  
bool push(LinkListQueue* queue,ElumType e) {  LNode* node = (LNode*)malloc(sizeof(LNode));  node->data = e;  //队列为空,头尾指针都指向node  if(queue->quelength == 0) {  queue->front = node;  queue->rear = node;  queue->quelength++;  }  else {  queue->rear->next = node;  queue->rear = node;  queue->quelength++;  }  return true;  
}

2.1.5访问队首元素

//访问队首元素  
ElumType peek(LinkListQueue* queue) {  if(queue->quelength == 0) {  printf("队空!\n");  return -1;  }  return queue->front->data;  
}

2.1.6出队

//出队  
ElumType pop(LinkListQueue* queue) {  ElumType num = peek(queue);  LNode *tmp = queue->front;  queue->front = queue->front->next;  free(tmp);  queue->quelength--;  return num;  
}

以上是栈与队列的一些基本操作,原版代码上传至(https://gitee.com/shi-chengfu)

如果有错误请联系QQ:303613518

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • linux命令学习-sed命令
  • Unity教程(十五)敌人战斗状态的实现
  • C#使用TCP-S7协议读写西门子PLC(五)-测试程序
  • 【C语言学习路线】
  • 【JavaScript】LeetCode:36-40
  • 系统架构设计师 需求分析篇一
  • vue中动态引入加载图片不显示
  • AI大模型与产品经理:替代与合作的深度剖析
  • 说⼀说hashCode()和equals()的关系
  • Corrupt block relative dba: 0x02c0b382 (file 11, block 45954)
  • 动态内存
  • 【Obsidian】当笔记接入AI,Copilot插件推荐
  • 函数模板(初阶)
  • C:字符串函数(续)-学习笔记
  • C语言中实现在动态库中访问另一个动态库变量
  • 2017 前端面试准备 - 收藏集 - 掘金
  • Android 控件背景颜色处理
  • JavaScript类型识别
  • JS数组方法汇总
  • js中forEach回调同异步问题
  • Just for fun——迅速写完快速排序
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • Mybatis初体验
  • nginx 负载服务器优化
  • SegmentFault 2015 Top Rank
  • ViewService——一种保证客户端与服务端同步的方法
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 前端工程化(Gulp、Webpack)-webpack
  • 使用 5W1H 写出高可读的 Git Commit Message
  • 提醒我喝水chrome插件开发指南
  • 一加3T解锁OEM、刷入TWRP、第三方ROM以及ROOT
  • gunicorn工作原理
  • ​flutter 代码混淆
  • (2)MFC+openGL单文档框架glFrame
  • (33)STM32——485实验笔记
  • (k8s)Kubernetes 从0到1容器编排之旅
  • (pojstep1.3.1)1017(构造法模拟)
  • (笔试题)合法字符串
  • (附源码)spring boot智能服药提醒app 毕业设计 102151
  • (六)vue-router+UI组件库
  • (论文阅读40-45)图像描述1
  • (生成器)yield与(迭代器)generator
  • (十六)一篇文章学会Java的常用API
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • (转)详解PHP处理密码的几种方式
  • (转)重识new
  • (转载)OpenStack Hacker养成指南
  • .Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • .NET 直连SAP HANA数据库
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • .net连接oracle数据库
  • @entity 不限字节长度的类型_一文读懂Redis常见对象类型的底层数据结构
  • [20160807][系统设计的三次迭代]
  • [3D基础]理解计算机3D图形学中的坐标系变换