C语言数据结构、第三节课----队列(链式存储)

一、概念:

队列是一种特殊的线性表,尽在两端进行操作,队头:取出数据元素的一端;队尾:插入数据元素的一端,队列是不允许在中间部位进行操作的,所以队列是先进先出,(first in first out  FIFO ) 允许插入的一端是队尾,允许删除的一端是队头。如图所示: 

  

上面就是队列的逻辑示意图,所以我们可以通过线性表的链式存储来模仿队列的链式存储。

二、队列的API函数:

1.队列的常用操作:

  1. 销毁队列
  2. 清空队列
  3. 进队列
  4. 出队列
  5. 获取队头元素
  6. 获取队列的长度

2.我们首先需要创建一个队列的业务逻辑结构体:

因为队列是特殊的线性表,所以我们写队列的链式存储的代码时候,我们利用了前面学习的线性表链式存储的代码:

1>queue.h

#ifndef __QUEUE__
#define __QUEUE__

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"seqlist.h"
typedef void queue;
queue * queue_create();
void queue_destroy(queue *q);
void queue_clear(queue *q);
int queue_append(queue *q,void *item);
void *queue_retrieve(queue *q);
void * queue_header(queue *q);
int queue_length(queue *q);

#endif 

2>queue.c

#include"queue.h"
typedef struct _queue_node
{
    list_node node;
    void *item; 
}queue_node;

queue * queue_create()
{
    int ret = 0;
    queue * tmp = NULL;
    tmp = seqlist_create();
    if (NULL == tmp)
    {
        ret = -1;
        printf("queue_create error :%d \n",ret);
        return NULL;
    }
    return tmp;
}
void queue_destroy(queue *q)
{
    seqlist_destroy(q);
    return;
}


void queue_clear(queue *q)
{
    seqlist_clear(q);
    return ;
}
int queue_append(queue *q,void *item)
{
    int ret= 0;
    queue_node *tmp = NULL;
    tmp = (queue_node *)malloc(sizeof(queue_node));
    if(NULL == tmp)
    {
        ret  = -1;
        printf("queue_append  malloc error :%d \n",ret);
        return ret;
    }
    memset(tmp,0,sizeof(queue_node));
    tmp->item = item;

    ret =  seqlist_insert(q,(list_node *)tmp,seqlist_length(q));
    if(ret != 0)
    {
        ret = -2;
        printf("queue_append  malloc error :%d \n",ret);
        return ret;
    }
    return 0;
}

//出队列,从线性表中删除0号位置元素
void *queue_retrieve(queue *q)
{
    int ret = 0;
    queue_node *tmp = NULL;
    void *tmp1 = NULL;
    tmp = (queue_node *)seqlist_delete(q,0);
    if(NULL == tmp)
    {
        ret =-1;
        printf("queue_retrieve error :%d \n",ret);
        return NULL;
    }
    tmp1 = tmp->item;
    if(tmp != NULL)
    {
        free(tmp);
    }
    return tmp1;
}
void* queue_header(queue *q)
{
    int ret = 0;
    queue_node *tmp = NULL;
    void * tmp1 = NULL;
    tmp = (queue_node *)seqlist_get(q,0);
    if(NULL == tmp)
    {
        ret = -1;
        printf("queue_header error :%d \n",ret);
        return NULL;
    }

    return tmp->item;
}
int queue_length(queue *q)
{
    return seqlist_length(q);
}

3>main.c(测试代码)

#include<stdio.h>
#include"queue.h"
int main(int argc,char* argv[])
{
    queue *qu = queue_create();
    int i = 0;
    int arr[10] = {0};
    for(i = 0;i < 10;i++)
    {
        arr[i] = i+10;
    }
    for(i = 0; i <10;i++)
    {
        queue_append(qu,&arr[i]);
    }
    int length = queue_length(qu);
    printf("队列的长度为:%D \n",length);

    int head = *((int *)queue_header(qu));
    printf("队首的位置为:%d \n",*((int *)queue_header(qu)));
    printf("一个一个清空队列 \n");
    for(i =0;i < 10;i++)
    {
        printf("插入的顺序元素为:%d",*((int *)queue_retrieve(qu)));
    }
    printf(" \n");

    return 0;
}

总结:

1.

typedef struct _queue_node
{
    list_node node;
    void *item; 
}queue_node;

在队列中,这个队列节点,和栈节点一样,这是用来定义一个中间变量的,因为我们传进来的是一个业务节点,而我们的队列用的是线性表来模仿的,所以,业务节点无法插进去队列,所以这个时候我们需要的是一个中间变量,充当线性表的节点,还可以同时将业务节点数据保存进线性表,所以我们定义了一个这样的中间数据类型;

2.整个代码是线性表来模仿队列,所以更能证明,其实队列就是一种特殊的线性表。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值