数据结构10分钟入门--队列
作者:互联网
一、队列是什么
队列是一种先进先出(First In First Out, FIFO)的线性存储结构,限定只能在表的一端(队尾)进行插入元素,表的另一端(队头)进行删除元素,数据元素进队列的过程称为入队,出队列的过程称为出队。
队列实现方式有数组和链表两种方式,本文介绍基于链表的实现方式,可以将队列理解为特殊的链表,只能在链表的头尾两端进行操作。
二、队列的结构体定义
typedef struct node {
int data; /**数据域*/
struct node *next; /**指向下一个节点*/
}queue_node;
typedef struct head {
int len; /**队列长度*/
queue_node *head; /**指向队头*/
queue_node *tail; /**指向队尾*/
}queue_head;
1、新定义了一个结构体queue_head
用来表示队列头,两个指针分别指向队列的两端,len
表示队列长度;
2、在单链表与栈中,由于无需双端操作,头指针的结构体定义与节点一致,所以复用节点的结构体,没有再重新定义。
三、函数清单
函数 | 描述 | 算法复杂度 |
---|---|---|
queue_init | 初始化队列,返回头指针 | O(1) |
queue_push | 元素入队 | O(1) |
queue_pop | 元素出队 | O(1) |
queue_release | 释放队列 | O(n) |
四、创建队列
/**创建队列,返回队列头*/
queue_head *queue_init()
{
/**创建队列头*/
queue_head *queue = (queue_head *)malloc(sizeof(queue_head));
if(queue == NULL) {
return NULL;
}
/**初始化队列头尾两个指针*/
queue->head = queue->tail = NULL;
queue->len = 0;
return queue;
}
- 因为目前队列中没有元素,是空队,
queue->head = queue->tail = NULL;
初始化队列的头尾指针为空 queue->len = 0;
初始化队列长度为0
五、入队
/**入队*/
int queue_push(queue_head *queue, int data)
{
/**创建一个节点*/
queue_node *node = (queue_node *)malloc(sizeof(queue_node));
if(node == NULL) {
return -1;
}
node->data = data;
/**在队尾插入元素*/
if (queue->len != 0) {
queue->tail->next = node;
queue->tail = node;
}
else {/**队列长度为0,插入第一个元素*/
queue->head = queue->tail = node;
node->next = queue->tail;
}
/**队列长度加1*/
queue->len++;
return 0;
}
- 入队分为两种情况,一种是当队列长度为0时,插入第一个元素,这时将队列头尾指针都指向该元素
- 另一种是当队列长度不为0时,插入元素,如下图,插入node2,虚线为去掉的,黄线为新增的。线1即
queue->tail->next = node;
线2即queue->tail = node;
六、出队
/**出队*/
int queue_pop(queue_head *queue)
{
int data = 0;
queue_node *p = queue->head;
/*判断队列中是否有数据,没有则返回异常*/
if (p == NULL || queue->len <= 0) {
return -1;
}
data = p->data;
/**将队列头指针指向第二个节点,完成第一个节点的出队*/
queue->head = p->next;
/**释放出队节点*/
if (p != NULL)
free(p);
/**队列长度减1*/
queue->len--;
if (queue->len <= 0) {
/**初始化队列头尾两个指针*/
queue->head = queue->tail = NULL;
}
return data;
}
出队则相对简单,queue->head = p->next;
将队列头指针跳过第一个节点,指向第二个节点,然后将第一个节点内存进行释放,返回第一个节点的值,完成出队。
七、释放队列
/**释放队列*/
int queue_release(queue_head *queue)
{
int len = queue->len;
queue_node *current, *next;
/**指向队列第一个节点*/
current = queue->head;
/**循环释放所有节点*/
while (len--)
{
next = current->next;
if (current != NULL)
free(current);
current = next;
}
queue->tail = queue->head = NULL;
queue->len = 0;
/**释放队列头*/
if (queue != NULL)
free(queue);
return 0;
}
八、编译测试
工程采用cmake构建,文件均经过测试,编译步骤如下:
1、mkdir build && cd build
2、cmake ../ && make
3、./queue_test
源码地址在公众号同标题文章底部,公众号:Linux杂货铺
系列文章
希望大家多关注支持!!
标签:node,10,head,--,len,queue,队列,tail,数据结构 来源: https://www.cnblogs.com/linux-misc/p/16673797.html