ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

数据结构10分钟入门--队列

2022-09-09 19:30:09  阅读:212  来源: 互联网

标签:node 10 head -- len queue 队列 tail 数据结构


一、队列是什么

队列是一种先进先出(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;
    image.png

六、出队

/**出队*/
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杂货铺

系列文章

数据结构10分钟入门--栈

[数据结构10分钟入门] 面向初学者从零实现 -- 单链表


希望大家多关注支持!!

标签:node,10,head,--,len,queue,队列,tail,数据结构
来源: https://www.cnblogs.com/linux-misc/p/16673797.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有