链队列和循环队列

1、编写函数,实现链式队列的基本操作;

2、编写函数,实现循环队列的基本操作。

创建两个指针(命名为 top 和 rear)分别指向链表中队列的队头元素和队尾元素

链式队列的初始状态


 

typedef struct QNode {   /* 结点类型*/
    QElemType   data;
    struct QNode  *next;
  } QNode, *QueuePtr;
typedef struct {    /* 链队列类型*/
    QueuePtr  front;  /* 队头指针*/
    QueuePtr  rear;   /* 队尾指针*/
} LinkQueue;
Status InitQueue (LinkQueue *Q) {
    /* 构造一个空队列Q*/
   QueuePtr p;
   p=(QueuePtr)malloc(sizeof(QNode));
   if (!p) exit (OVERFLOW);
           /*存储分配失败*/
   p->next = NULL;
   Q->front=p;
   Q->rear=p;
   return OK;
}

链队队列中,当有新的数据元素入队,只需进行以下 3 步操作:

  1. 将该数据元素用节点包裹,例如新节点名称为 newnode;
  2. 与 rear 指针指向的节点建立逻辑关系,即执行 rear->next=newnode;
  3. 最后移动 rear 指针指向该新节点,即 rear=newnode;

由此,新节点就入队成功了。
例如,在图 1 的基础上,我们依次将 {1,2,3} 依次入队,各个数据元素入队的过程如图 2 所示:

{1,2,3} 入链式队列

Status CreateQueue (LinkQueue *Q,int n) {
   /* 创建n个元素的队列Q*/
	QueuePtr newnode;
	int i;
	for (i=1;i<=n;i++)
	{newnode=(QueuePtr)malloc(sizeof(QNode));
   		if (!newnode) exit (OVERFLOW);
           /*存储分配失败*/
    	scanf("%d",&newnode->data); 
		newnode->next = NULL;
    	Q->rear->next = newnode;    
		Q->rear = newnode;
	}
   return OK;
}
//入列操作
Status EnQueue (LinkQueue *Q,QElemType e) {
	QueuePtr newnode;//创建一个新的结点 
	newnode=(QueuePtr)malloc(sizeof(QNode));//给结点分配一个空间 
	newnode->data=e;
	newnode->next=NULL;
	Q->rear->next=newnode;//尾结点指向新结点 
	Q->rear=newnode;//尾结点变成最后一个结点 
	return OK;
}

当链式队列中,有数据元素需要出队时,按照 "先进先出" 的原则,只需将存储该数据的节点以及它之前入队的元素节点按照原则依次出队即可。


链式队列中队头元素出队,需要做以下 3 步操作:

  1. 通过 top 指针直接找到队头节点,创建一个新指针 p 指向此即将出队的节点;
  2. 将 p 节点(即要出队的队头节点)从链表中摘除;
  3. 释放节点 p,回收其所占的内存空间;


例如,在图 2b) 的基础上,我们将元素 1 和 2 出队,则操作过程如图 3 所示:

链式队列中数据元素出队

Status DeQueue (LinkQueue *Q,QElemType *e) {
  /* 若队列不空,则删除Q的队头元素,
  用 e 返回其值,并返回OK;否则返回ERROR*/
    /*请完成函数*/
   	QueuePtr p;//p用来存放删除的元素 
	if(Q->rear==Q->front)//即队列为空 
	return ERROR;
	p=Q->front->next;//p指向表头元素的下一个元素 ,即要删除的结点 
	*e=p->data;//存放值到p数据域 
	Q->front->next=p->next;//p指向要删除结点的下一个结点 
	if(Q->rear==p) Q->rear=Q->front;
	return OK; 
	free(p);
}
//队列的遍历
Status QueueTraverse(LinkQueue Q)
{
	QueuePtr p;
	p=Q.front;
	printf("\n");
	while(p!=Q.rear)
	{ printf("%d   ",p->next->data);p=p->next;}
}
//一下是总代码
#include "stdio.h"
#include "math.h"
#include "stdlib.h"
#define OK   1
#define ERROR 0
#define MAXSIZE 100
typedef int Status;
typedef int QElemType;
typedef struct QNode {/* 结点类型*/
    QElemType   data;
    struct QNode  *next;
  } QNode, *QueuePtr;
typedef struct { /* 链队列类型*/
    QueuePtr  front;  /* 队头指针*/
    QueuePtr  rear;   /* 队尾指针*/
} LinkQueue;
Status InitQueue (LinkQueue *Q) {
   /* 构造一个空队列Q*/
   QueuePtr p;
   p=(QueuePtr)malloc(sizeof(QNode));
   if (!p) exit (OVERFLOW);
           /*存储分配失败*/
   p->next = NULL;
   Q->front=p;
   Q->rear=p;
   return OK;
}
Status CreateQueue (LinkQueue *Q,int n) {
   /* 创建n个元素的队列Q*/
	QueuePtr newnode;
	int i;
	for (i=1;i<=n;i++)
	{newnode=(QueuePtr)malloc(sizeof(QNode));
   		if (!newnode) exit (OVERFLOW);
           /*存储分配失败*/
    	scanf("%d",&newnode->data); 
		newnode->next = NULL;
    	Q->rear->next = newnode;    
		Q->rear = newnode;
	}
   return OK;
}
Status EnQueue (LinkQueue *Q,QElemType e) {
	QueuePtr newnode;//创建一个新的结点 
	newnode=(QueuePtr)malloc(sizeof(QNode));//给结点分配一个空间 
	newnode->data=e;
	newnode->next=NULL;
	Q->rear->next=newnode;//尾结点指向新结点 
	Q->rear=newnode;//尾结点变成最后一个结点 
	return OK;
}
Status DeQueue (LinkQueue *Q,QElemType *e) {
  /* 若队列不空,则删除Q的队头元素,
  用 e 返回其值,并返回OK;否则返回ERROR*/
    /*请完成函数*/
   	QueuePtr p;//p用来存放删除的元素 
	if(Q->rear==Q->front)//即队列为空 
	return ERROR;
	p=Q->front->next;//p指向表头元素的下一个元素 ,即要删除的结点 
	*e=p->data;//存放值到p数据域 
	Q->front->next=p->next;//p指向要删除结点的下一个结点 
	if(Q->rear==p) Q->rear=Q->front;
	return OK; 
	free(p);

}
Status QueueTraverse(LinkQueue Q)
{
	QueuePtr p;
	p=Q.front;
	printf("\n");
	while(p!=Q.rear)
	{ printf("%d   ",p->next->data);p=p->next;}
}

main()
{int n,e;
	LinkQueue Q;
	InitQueue(&Q);
	printf("input n=?");
	scanf("%d",&n);
	CreateQueue(&Q,n);
	QueueTraverse(Q);
	EnQueue(&Q,30);
	QueueTraverse(Q);
	DeQueue(&Q,&e);
	QueueTraverse(Q);
	printf("\ne=%d",e);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值