IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 队列的实现-C语言 -> 正文阅读

[C++知识库]队列的实现-C语言


注:本文系岭南师范学院物联网俱乐部原创部分训练计划,转载请保留声明。

前言

前面跟大家讨论了堆栈的几种办法,如静态数组堆栈、动态数组堆栈和链表堆栈,今天主要跟大家讲一下队列的实现,队列是一种“先进先出的数据结构”,可分为静态队列和链式队列。链式队列则是通过尾插法实现,静态队列一般使用数组实现,数组需要预先定义内存大小,为了避免内存浪费,一般使用循环队列。

一、链式队列

/*
引用头文件""和<>的区别
#include" "引用的是你程序目录的相对路径中的头文件。
#include< >引用的是编译器的类库路径里面的头文件。

stdio .h 头文件定义了三个变量类型、一些宏和各种函数来执行输入和输出。
C 标准库的 assert.h头文件提供了一个名为 assert 的宏,它可用于验证程序做出的假设,并在假设为假时输出诊断消息。
C 库函数 void *malloc(size_t size) 分配所需的内存空间,并返回一个指向它的指针。

思路:?头插法和尾插法顾名思义,就是在链表加入新结点的时候是在头部插入还是在尾部插入。
?尾插法不改变链表的原本顺序,在遍历链表的时候,正好就对应了队列的先进先出的特性;
头插法会改变链表原本的顺序,在遍历链表的时候也是正好对应了栈的先进后出的特性。

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/***********定义一个结构体类型,在文本段***************/
typedef struct queue
{
 int value;            //数据域
 struct queue *next;   //指针域
}queue_t;


queue_t *head; //定义头指针,在栈区
queue_t *tail; //定义尾指针,在栈区
queue_t *prt;  //定义指针变量prt用于遍历,在栈区

/******定义一个判断头结点为空的函数,在文本段********/
unsigned int empty()
{
  return head == NULL; //如果头结点为空,返回1
}

/******定义一个增加队列函数,在文本段********/
void add_queue()
{
  queue_t *new_node;	                            //建立一个指针变量
  for(int num=0;num<8;num++)                      //用一个for循环来循环创建新的结点
  { 
  new_node = (queue_t*)malloc(sizeof(queue_t));   //malloc申请一块内存给新节点并存在指针中,new_node指向这个内存的首地
  memset(new_node,0,sizeof(*new_node));//memset是设置new_node指向的这个首地址开始到首地址+sizeof(*new_node)这个长度元素为0
  new_node->next=NULL;                 //内存(结构体)的指针域为0
  new_node->value=num+1;               //内存(结构体)数据域增加数据
  if(head == NULL )                    //若头指针为空,则是第一个结点,new_node存的地址给head,head指向首个节点
  {
   head=new_node;
  }
  else                                  //若头指针不为空,new_node存的地址给tail指向现在的这个节点的指针域(如第二个节点),这个时候第二个节点将会连接第三个节点
  {
   tail->next=new_node;
  }
   tail=new_node;                       //ew_node存的地址给tail,这个时候tail也会连接下一个节点(如:第三个节点)
  }
}

/******定义一个删除队列函数,在文本段********/
void delete_queue()
{
 queue_t *first_node;       //定义一个新的指针变量
 first_node = head;         //head指针的值给了first_node,first将会指向head本来连接的节点(如第二个节点)
 head = first_node->next;   //first_node能获取已经连接的节点的指针域(如第二个节点),这个指针域存在了连接下一个节点的地址(如第三节点),赋值给head,head将会指向这个节点
 free(first_node);          //释放掉first_node,即清除第二个节点的内存
 if(head == NULL)           //主要考虑到特殊情况,如剩下最后一个节点时,想将它清掉,需要头指针指向为0,尾指针也为0
 {
  tail==NULL;
 }
}

/******定义一个销毁队列函数,在文本段********/
void destroy_queue()         //判断队列是否为空,可一个一个一个破坏       
{
 if(!empty())
 {
  delete_queue();
 }
}

int main()
{
 printf("创建队列:");
 add_queue();
 for(prt=head;prt!=NULL;prt=prt->next)  //循环实现遍历,意思为每循环一次,prt指向新的节点
 {
  printf("%d\n",prt->value);            //prt指向新的节点后,便能拿到里面的value值(数据域)
 }
  printf("\n\n");

  printf("删除队列");

  for(int i=0;i<4;i++)
 {
  delete_queue();
 }
  for(prt=head;prt!=NULL;prt=prt->next)
 {
  printf("%d\n",prt->value);
 }
  printf("\n\n");

}

二、循环队列

/*
引用头文件""和<>的区别
#include" "引用的是你程序目录的相对路径中的头文件。
#include< >引用的是编译器的类库路径里面的头文件。

stdio .h 头文件定义了三个变量类型、一些宏和各种函数来执行输入和输出。
C 标准库的 assert.h头文件提供了一个名为 assert 的宏,它可用于验证程序做出的假设,并在假设为假时输出诊断消息。
C 库函数 void *malloc(size_t size) 分配所需的内存空间,并返回一个指向它的指针。

思路:队列是一种“先进先出的数据结构”,可分为静态队列和链式队列。
静态队列一般使用数组实现,数组需要预先定义内存大小,为了避免内存浪费,一般使用循环队列。接下来讲述循环队列的原理以及实现代码。
->:在用结构体指针的时候才能用,常用与指针变量指向结构体成员的值

提示:front和rear不会超过max——queue_num,并且作为data数组的下标
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define max_queue_num 10 //循环队列的最大长度

typedef struct cir_queue //定义一个cir_queue结构体
{
 int front;              //指向队列头,指向第一个数据节点
 int rear;               //指向队尾列(并不是指向最后一个数据节点,而是最后一个数据节点的位置)
 char data[max_queue_num];//节点数据,根据实际需要可以是不同的数据类型,但因为是数组,需要在声明时候指定大小。
}queue_t;

void queue_init(queue_t *queue)//初始化data的数组的数据,front和rear设为0
{
 queue->front=0;
 queue->rear=0;
 /*
 memset()函数,意思:queue->data这个是指针或者数组的地址,填充(替换)max_queue_num长度的地址里面的内容变为0
 在memset()函数里,queue->data是一个地址
但是像new_node->value=value这样子,new_node->value是value这个地址里面的址。
 */memset(queue->data,0,max_queue_num);
}

int empty(queue_t *queue )//
{
  return (queue->front == queue->rear);//头指针等于尾指针就为空
}

int full(queue_t *queue)
{
  return(((queue->rear+1)%max_queue_num == queue->front));//当real等于9的时候,加上1等于10除10,余数为0,与front相等,所以满了,但其实这个时候real只是等9
}

void destroy_queue(queue_t *queue)
{
  if(queue == NULL)
  {
    printf("队列不存在");
  }
  else
  {
   free(queue);
  }
}

void add_queue(queue_t *queue , char newdata)
{
 if(full(queue))
 {
  printf("队列已满!");
  return ;
 }
 queue->data[queue->rear]=newdata;//这里的rear不会到9,因为一当9,就是打印队列已经满了
 queue->rear=(queue->rear+1)%max_queue_num;//用(queue->rear+1)%max_queue_num为了防止队列已经满的状态下,删光,重新加,这样子rear超过max_queue_num
}

void delete_queue(queue_t *queue)
{
 if(empty(queue))
 {
   printf("队列为空!");
   return ;
 }
  queue->front=(queue->front+1)%max_queue_num;//从头开始删除
}

void queue_print(queue_t *queue)
{
 for(int num=queue->front;num!=queue->rear;num=(num+1)%max_queue_num)
 {
  printf("%c\n",queue->data[num]);  //从头开始打印
 }
}

int main()
{
  queue_t *que=(queue_t*)malloc(sizeof(queue_t));
  if(!que)
  {
   printf("malloc分配失败!");
  }
  queue_init(que);
  printf("新建队列");
  add_queue(que,'a');
  add_queue(que,'b');
  add_queue(que,'c');
  queue_print(que);
  printf("\n");
 
  printf("删除队列");
  delete_queue(que);
  queue_print(que);

}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-15 23:42:02  更:2021-07-15 23:42:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/5 5:18:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码