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

数据结构-3.6.队列的链式实现

队列可以理解为单链表的阉割版,相比单链表而言,队列只有在添加和删除元素上和单链表有区别


一.队列的链式实现:

1.图解:

2.代码:

#include<stdio.h>
​
typedef struct LinkNode //链式队列结点 
{int data;struct LinkNode *next;
}LinkNode;
​
typedef struct //链式队列 
{LinkNode *front; //队头指针LinkNode *rear; //队尾指针 
}LinkQueue;
​
int main()
{return 0;
}

二.初始化队列:

1.带头结点:

a.图解:

b.代码:
#include<stdio.h>
#include<stdlib.h>
​
typedef struct LinkNode //链式队列结点 
{int data;struct LinkNode *next;
}LinkNode;
​
typedef struct //链式队列 
{LinkNode *front; //队头指针LinkNode *rear; //队尾指针 
}LinkQueue;
​
//初始化队列(带头结点)
void InitQueue(LinkQueue &Q)
{//初始化时,front和rear都指向头结点Q.front = Q.rear = (LinkNode *)malloc(sizeof(LinkNode));//malloc用于申请一个头结点 Q.front -> next=NULL; //头指针下一个元素为NULL,因为一开始什么都没有 
} 
​
//判断队列是否为空
bool IsEmpty(LinkQueue Q)
{if( Q.front==Q.rear ) //也可以这么判断:如果Q.front -> next==NULL,此时队列为空 {return true; //代表队列为空 }else{return false; //代表队列不为空 }
} 
​
int main()
{LinkQueue Q;//声明一个队列InitQueue(Q); //初始化队列//后续操作。。。 return 0;
}

2.不带头结点:

a.图解:

b.代码:
#include<stdio.h>
​
typedef struct LinkNode //链式队列结点 
{int data;struct LinkNode *next;
}LinkNode;
​
typedef struct //链式队列 
{LinkNode *front; //队头指针LinkNode *rear; //队尾指针 
}LinkQueue;
​
//初始化队列(不带头结点)
void InitQueue(LinkQueue &Q)
{//初始化时,front和rear都指向NULLQ.front=NULL;Q.rear=NULL; 
}
​
//判断队列是否为空
bool IsEmpty(LinkQueue Q)
{if( Q.front==NULL ) //只需要看头指针是否等于NULL即可,也可以看Q.rear是否为NULL,是的话队列为空 {return true; //代表队列为空,头指针为NULL,代表没有头指针,自然队列为空 }else{return false; //代表队列不为空 }
}  
​
int main()
{LinkQueue Q;//声明一个队列InitQueue(Q); //初始化队列//后续操作。。。return 0;
}

三.入队操作:

1.带头结点:

a.图解:

b.代码:
#include<stdio.h>
#include<stdlib.h>
​
typedef struct LinkNode //链式队列结点 
{int data;struct LinkNode *next;
}LinkNode;
​
typedef struct //链式队列 
{LinkNode *front; //队头指针LinkNode *rear; //队尾指针 
}LinkQueue;
​
//初始化队列(带头结点)
void InitQueue(LinkQueue &Q)
{//初始化时,front和rear都指向头结点Q.front = Q.rear = (LinkNode *)malloc(sizeof(LinkNode));//malloc用于申请一个头结点 Q.front -> next=NULL; //头指针下一个元素为NULL,因为一开始什么都没有 
} 
​
//判断队列是否为空
bool IsEmpty(LinkQueue Q)
{if( Q.front==Q.rear ) //也可以这么判断:如果Q.front -> next==NULL,此时队列为空 {return true; //代表队列为空 }else{return false; //代表队列不为空 }
} 
​
//新元素入队(带头结点)
void EnQueue(LinkQueue &Q,int x)//只是让x入队,不改变x的值,所以无需&
{LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode)); //用malloc申请一个新结点用来存要入队的元素 s->data = x; //把新插入的元素x放入新结点中 s->next = NULL; //由于队列入队的操作是在表尾的位置进行,因此新插入的结点是队列的最后一个结点,后面就是NULL Q.rear->next = s;/*由于一开始rear指针指向的是当前的表尾结点,而新插入的新结点应该连到表尾结点之后,所以要把rear指向的结点next指针域指向新结点s */Q.rear = s; //修改表尾指针指向新添加的元素,新添加的元素就是表尾元素 
} 
​
int main()
{LinkQueue Q;//声明一个队列InitQueue(Q); //初始化队列//后续操作。。。 return 0;
}

2.不带头结点:

a.图解:

b.代码:
#include<stdio.h>
#include<stdlib.h> 
​
typedef struct LinkNode //链式队列结点 
{int data;struct LinkNode *next;
}LinkNode;
​
typedef struct //链式队列 
{LinkNode *front; //队头指针LinkNode *rear; //队尾指针 
}LinkQueue;
​
//初始化队列(不带头结点)
void InitQueue(LinkQueue &Q)
{//初始化时,front和rear都指向NULLQ.front=NULL;Q.rear=NULL; 
}
​
//判断队列是否为空
bool IsEmpty(LinkQueue Q)
{if( Q.front==NULL ) //只需要看头指针是否等于NULL即可,也可以看Q.rear是否为NULL,是的话队列为空 {return true; //代表队列为空,头指针为NULL,代表没有头指针,自然队列为空 }else{return false; //代表队列不为空 }
}  
​
//新元素入队(不带头结点)
void EnQueue(LinkQueue &Q,int x)
{LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));//用malloc申请一个新结点用来存要入队的元素 s->data = x;//把新插入的元素x放入新结点中s->next = NULL;//由于队列入队的操作是在表尾的位置进行,因此新插入的结点是队列的最后一个结点,后面就是NULL if( Q.front==NULL ) //在空队列中插入第一个元素,插入第一个元素时Q.front为NULL,因为刚开始front和rear都指向NULL { //如果队列为空,那么插入的元素就是队列第一个元素 //修改队头和队尾指针 Q.front = s;Q.rear = s;}else{Q.rear->next = s;//新结点插入到rear结点之后 Q.rear = s;//修改rear指针 }
} 
​
int main()
{LinkQueue Q;//声明一个队列InitQueue(Q); //初始化队列//后续操作。。。return 0;
}

四.出队操作:

1.带头结点:

a.图解:

不是最后一个元素出队:

最后一个元素出队:

b.代码:
#include<stdio.h>
#include<stdlib.h>
​
typedef struct LinkNode //链式队列结点 
{int data;struct LinkNode *next;
}LinkNode;
​
typedef struct //链式队列 
{LinkNode *front; //队头指针LinkNode *rear; //队尾指针 
}LinkQueue;
​
//初始化队列(带头结点)
void InitQueue(LinkQueue &Q)
{//初始化时,front和rear都指向头结点Q.front = Q.rear = (LinkNode *)malloc(sizeof(LinkNode));//malloc用于申请一个头结点 Q.front -> next=NULL; //头指针下一个元素为NULL,因为一开始什么都没有 
} 
​
//判断队列是否为空
bool IsEmpty(LinkQueue Q)
{if( Q.front==Q.rear ) //也可以这么判断:如果Q.front -> next==NULL,此时队列为空 {return true; //代表队列为空 }else{return false; //代表队列不为空 }
} 
​
//队头元素出队(带头结点)
bool DeQueue(LinkQueue &Q,int &x) //最终x会变为要删除的元素,所以需要& 
{if( Q.front==Q.rear ){return false;//空队,就无法出队即删除元素 }//此时队列不为空//Q.front为头结点 LinkNode *p = Q.front->next; //让p指针指向要删除的结点,对于带头结点的队列来说就是要删除头结点的后一个结点 x = p->data; //用变量x返回队头元素即要删除的元素 Q.front->next = p->next; //修改头结点的next指针if( Q.rear==p ) //此次是最后一个结点出队,最终就是空队列即Q.rear=Q.front {Q.rear=Q.front; //修改rear指针 } free(p); //释放结点空间return true; 
} 
​
int main()
{LinkQueue Q;//声明一个队列InitQueue(Q); //初始化队列//后续操作。。。 return 0;
}

2.不带头结点:

a.图解:

b.代码:
#include<stdio.h>
#include<stdlib.h>
​
typedef struct LinkNode //链式队列结点 
{int data;struct LinkNode *next;
}LinkNode;
​
typedef struct //链式队列 
{LinkNode *front; //队头指针LinkNode *rear; //队尾指针 
}LinkQueue;
​
//初始化队列(不带头结点)
void InitQueue(LinkQueue &Q)
{//初始化时,front和rear都指向NULLQ.front=NULL;Q.rear=NULL; 
}
​
//判断队列是否为空
bool IsEmpty(LinkQueue Q)
{if( Q.front==NULL ) //只需要看头指针是否等于NULL即可,也可以看Q.rear是否为NULL,是的话队列为空 {return true; //代表队列为空,头指针为NULL,代表没有头指针,自然队列为空 }else{return false; //代表队列不为空 }
}  
​
//队头元素出队(不带头结点)
bool DeQueue(LinkQueue &Q,int &x)
{if( Q.front==NULL ){return false; //空队 }LinkNode *p=Q.front; //p指向此次出队的结点即front指针指向的结点出队 x = p->data; //用变量x返回队头元素 Q.front = p->next; //由于没有头结点,所以每次有队头元素出队后都需要修改front指针的指向 if( Q.rear==p ) //此次是最后一个结点出队,最终就是空队列 {Q.front=NULL; //front指向NULL Q.rear=NULL; //rear指向NULL  } free(p); //释放结点空间 return true; 
} 
​
int main()
{LinkQueue Q;//声明一个队列InitQueue(Q); //初始化队列//后续操作。。。return 0;
}

五.队列满的条件:


六.统计队列的长度:

思路:

从队头结点开始依次往后遍历,统计总共有多少个结点,显然时间复杂度为O(n)。


七.总结:


相关文章:

  • 集合框架 - Collection单列集合
  • WeChat_DevTools 断点调试方法总结
  • 0x09 瑞友 应用虚拟化系统 GetBSAppUrl SQL注入漏洞 - 复现
  • 图像超分辨率(SR)
  • linux系统的常用命令
  • GPIO端口的使用
  • 牛客周赛 Round 61(思维、组合数)
  • 关于三维布尔运算的思考(2)
  • 深入理解 WebSocket:实时通信的利器
  • 如何使用 DomCrawler 进行复杂的网页数据抓取?
  • InnoDB架构
  • Mavn解决依赖不重新下载,主动下载依赖
  • 什么?你想通过网络安全月入千万?看看AI的回答(包含注释版)
  • 自动化学习3:日志记录及测试报告的生成--自动化框架搭建
  • Django 数据库配置以及字段设置详解
  • EOS是什么
  • gf框架之分页模块(五) - 自定义分页
  • Github访问慢解决办法
  • iOS编译提示和导航提示
  • IOS评论框不贴底(ios12新bug)
  • JSDuck 与 AngularJS 融合技巧
  • k8s如何管理Pod
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • QQ浏览器x5内核的兼容性问题
  • React Transition Group -- Transition 组件
  • Redis中的lru算法实现
  • Spring Boot MyBatis配置多种数据库
  • Sublime Text 2/3 绑定Eclipse快捷键
  • Vue学习第二天
  • Yeoman_Bower_Grunt
  • 小程序01:wepy框架整合iview webapp UI
  • 一起参Ember.js讨论、问答社区。
  • const的用法,特别是用在函数前面与后面的区别
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • %@ page import=%的用法
  • (7) cmake 编译C++程序(二)
  • (a /b)*c的值
  • (二)fiber的基本认识
  • (二十九)STL map容器(映射)与STL pair容器(值对)
  • (机器学习的矩阵)(向量、矩阵与多元线性回归)
  • (十) 初识 Docker file
  • (四) 虚拟摄像头vivi体验
  • (四)搭建容器云管理平台笔记—安装ETCD(不使用证书)
  • (算法)大数的进制转换
  • (一)Linux+Windows下安装ffmpeg
  • **登录+JWT+异常处理+拦截器+ThreadLocal-开发思想与代码实现**
  • .Net Core 微服务之Consul(二)-集群搭建
  • .NET Standard、.NET Framework 、.NET Core三者的关系与区别?
  • .net 使用$.ajax实现从前台调用后台方法(包含静态方法和非静态方法调用)
  • .NET设计模式(11):组合模式(Composite Pattern)
  • .pyc文件还原.py文件_Python什么情况下会生成pyc文件?
  • @kafkalistener消费不到消息_消息队列对战之RabbitMq 大战 kafka
  • [ 云计算 | AWS 实践 ] 基于 Amazon S3 协议搭建个人云存储服务
  • [12] 使用 CUDA 加速排序算法
  • [14]内置对象