数据结构之链队列

4.13 队列的链式存储结构及实现
队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已,我们简称为链队列。我们将队头指针指向链队列的头结点,而队尾指针指向终端节点。
       头结点    队头                   队尾
front           a1                      an NULL
 rear
空队列时,front和rear都指向头结点。
头结点
front        NULL
         rear

4.13.4 循环队列和链队列
时间上  基本操作都是常数时间,即都为0(1)的,不过循环队列是事先申请好的 空间,使用期间不释放。  而对于链队列,每次申请和释放结点也会存在一些   时间开销。
空间上  循环队列必须有一个固定的长度,所以就有了存储元素个数和空间浪费的 问题。而链队列不存在这个问题,尽管它需要一个指针域,会产生一些空间上 的开销。空间上,链队列更加灵活。

总之,在可以确定队列长度最大值的情况下,建议用循环队列

无法预估队列的长度时,则用链队列。

链队列程序如下所示:

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


//定义结点数据类型
typedef struct Node
{
int data;
struct Node *next;
} node,*pnode;


//队列的链表结构
typedef struct Queue
{
pnode front;
pnode rear;  //队头队尾指针
} queue,*pqueue;


//函数声明


//构造空队列
void init_queue(pqueue list);
//入队
void en_queue(pqueue list,int val);
//遍历
void traverse(pqueue list);
//出队
bool de_queue(pqueue list,int *val);
//队列为空
bool empty_queue(pqueue list);


int main(void)
{
queue list;
int val;

init_queue(&list);
    en_queue(&list,1);
en_queue(&list,2);
en_queue(&list,3);
en_queue(&list,4);
    en_queue(&list,5);
en_queue(&list,6);


traverse(&list);
if(de_queue(&list,&val))
{
printf("出队成功,出队的元素是:%d.\n",val);
}
else
{
printf("出队失败!\n");
}


traverse(&list);
return 0;
}
//构造空队列
void init_queue(pqueue list)
{
list->front = (pnode)malloc(sizeof(node));
if(list->front == NULL)
{
printf("分配内存失败!\n");
exit(-1);
}
else
{
list->rear = list->front;


list->front->next = NULL;
list->rear->next  = NULL;
}
}
//插入元素val为新的队尾元素 入队
/**********************************************************
front


头结点  a1    a2    a3     a4.............an      s
                                                 e NULL
 rear
**********************************************************/
void en_queue(pqueue list,int val)
{
pnode p;
p = (pnode)malloc(sizeof(node));
if(p == NULL)
{
printf("分配内存失败!\n");
exit(-1);
}


p->data = val;
p->next = NULL;


list->rear->next = p; //把拥有元素e新结点p赋值给原队尾结点的后继


list->rear = p;       //把当前的p设置为队尾结点,rear指向p
return ;
}
//遍历输出
void traverse(pqueue list)
{
pnode p;
p = list->front->next;


while(p != NULL)
{
printf("%d ",p->data);
p = p->next;
}


printf("\n");
return ;
}
//队列为空
bool empty_queue(pqueue list)
{
if(list->front == list->rear)
{
return true;
}
else
{
return false;
}
}
//出队
/**************************************************************
出队操作时,就是头结点的后继结点出队,将头结点的后继改为它后面的结点


若链表除过头结点外只剩一个元素时,则需要将rear指向头结点。
**************************************************************/
bool de_queue(pqueue list,int *val)
{
if(empty_queue(list))
{
return false;
}
else
{
pnode p;
p = list->front->next; //头结点不能丢,将欲删除的队头结点暂存给p


*val = p->data;        //将欲删除的队头结点的值赋值给e
list->front->next = p->next;   //将原队头结点后继p->next赋值给头结点后继


if(list->rear == p)   //若队头是队尾,则删除后将rear指向头结点。
{
list->rear = list->front;
}
free(p);


return true;
}
}





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值