数据结构与算法(C语言)------队列

队列

一、定义

队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
允许插入的一端称为队尾,允许删除的一端称为队头。队列是一种先进先出的线性表。

二、代码

1、代码(队列的顺序存储结构—循环队列)

#ifndef __SEQQUEUE_H
#define __SEQQUEUE_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define OK    1
#define ERROR 0
typedef int states;

#define MAX_SIZE 100
typedef int ElementType;
//队列的顺序存储结构
typedef struct {
	ElementType data[MAX_SIZE];
	int front;
	int rear;
}SeqQueue;

/** 初始化队列 */
states InitQueue(SeqQueue *Q);

/** 入队 */
states EnQueue(SeqQueue *Q, ElementType e);

/** 出队 */
states DeQueue(SeqQueue *Q, ElementType *e);

/** 获取队列中的元素个数 */
int GetQueueLength(SeqQueue *Q);

/** 清空队列 */
states ClearQueue(SeqQueue *Q);

/** 打印队列中的元素 */
void PrintfQueue(SeqQueue *Q);

#endif /* __SEQQUEUE_H */
#include "SeqQueue.h"

/** 初始化队列 */
states InitQueue(SeqQueue *Q)
{
	Q->front = 0;
	Q->rear = 0;
	return OK;
}

/** 入队 */
states EnQueue(SeqQueue *Q, ElementType e)
{
	//判断循环队列是否已满
	if((Q->rear + 1) % MAX_SIZE == Q->front)
		return ERROR;
	Q->data[Q->rear] = e;
	Q->rear = (Q->rear + 1) % MAX_SIZE;
	return OK;
}

/** 出队 */
states DeQueue(SeqQueue *Q, ElementType *e)
{
	//判断队列是否为空
	if(Q->front == Q->rear)
		return ERROR;
	*e = Q->data[Q->front];
	Q->front = (Q->front + 1) % MAX_SIZE;
	return OK;
}

/** 获取队列中的元素个数 */
int GetQueueLength(SeqQueue *Q)
{	
	return ((Q->rear - Q->front + MAX_SIZE) % MAX_SIZE);
}

/** 清空队列 */
states ClearQueue(SeqQueue *Q)
{
	Q->front = 0;
	Q->rear = 0;
	return OK;
}

/** 打印队列中的元素 */
void PrintfQueue(SeqQueue *Q)
{
	int i = Q->front;
	printf("队列:");
	while(i != Q->rear){
		printf("%d ",Q->data[i]);
		i++;
	}
}

2、代码(队列的链式存储结构)

#ifndef __LINKEDQUEUE_H
#define __LINKEDQUEUE_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define OK    1
#define ERROR 0
typedef int states;

//队列的链式存储结构
/** 队列中的结点结构 */
typedef struct QueueNode{
	ElementType data;
	struct QueueNode *next;
}QueueNode;

/** 队列结构 */
typedef struct {
	QueueNode *front;
	QueueNode *rear;
}LinkedQueue;

/** 队列的初始化 */
states InitLinkedQueue(LinkedQueue *Q);

/** 入队 */
states EnLinkedQueue(LinkedQueue *Q, ElementType e);

/** 出队 */
states DeLinkedQueue(LinkedQueue *Q, ElementType *e);

/** 获取队列中的元素个数 */
int GetLinkedQueueElemNum(LinkedQueue *Q);

/** 清空队列 */
states ClearLinkedQueue(LinkedQueue *Q);

/** 打印队列中的元素 */
void PrintfLinkedQueue(LinkedQueue *Q);

#endif /* __LINKEDQUEUE_H */
#include "LinkedQueue.h"

/** 队列的初始化 */
states InitLinkedQueue(LinkedQueue *Q)
{
	Q->front = (QueueNode *)malloc(sizeof(QueueNode));
	Q->rear = Q->front;
	Q->front->next = NULL;
	return OK;
}

/** 入队 */
states EnLinkedQueue(LinkedQueue *Q, ElementType e)
{
	QueueNode *node = (QueueNode *)malloc(sizeof(QueueNode));
	printf("node = 0x%x\n",node);
	node->data = e;
	node->next = NULL;
	Q->rear->next = node;
	Q->rear = node;
	return OK;
}

/** 出队 */
states DeLinkedQueue(LinkedQueue *Q, ElementType *e)
{
	QueueNode *node;
	//判断队列是否为空
	if(Q->rear == Q->front)
		return ERROR;
	node = Q->front->next;
	*e = node->data;
	Q->front->next  = node->next;
	if(Q->rear == node){            //重点理解
		Q->rear = Q->front;         //rear指针是移动的,front->next指针也是移动的
		                            //front指针是不动的,									
	}
	free(node);
	return OK;
}

/** 获取队列中的元素个数 */
int GetLinkedQueueElemNum(LinkedQueue *Q)
{
	int ElemNbr = 0;
	QueueNode *node = Q->front->next;
	while(node){
		node = node->next;
		ElemNbr++;
	}
	return ElemNbr;
}

/** 清空队列 */
states ClearLinkedQueue(LinkedQueue *Q)
{
	QueueNode *p,*q;
	p= Q->front->next;
	while(p){
		q = p->next;
		free(p);
		p = q;
	}
	Q->rear = Q->front;
	Q->front->next = NULL;
	return OK;
}

/** 打印队列中的元素 */
void PrintfLinkedQueue(LinkedQueue *Q)
{
	QueueNode *node = Q->front->next;
	while(node){
		printf("%d ",node->data);
		node = node->next;
	}
}

三、编程笔记

  • 顺序队列
    1、顺序队列的结构表示
    typedef struct {
    int front; //队头指针
    int rear; //队尾指针
    ElementType datas[MAX_SIZE];
    }QueueList;
    2、队列为空的判断条件:队头指针与队尾指针相等时,队列为空。
    3、队列已满的判断条件:队尾指针加1等于队头指针时,队列已满。
    这里是人为规定的,为了和队列为空进行区别。因此,数组中的一个元素是不用的。
    4、获取队列中的元素个数:
    当rear > front时,num = rear - front;
    当rear < front时,num = rear + MAX_SIZE - front;
    合并成一个表达式:num = (rear + MAX_SIZE - front)%MAX_SIZE;

  • 链式队列
    1、采用了头结点,
    2、队列为空的判断条件
    3、将队列中的最后一个元素出队之后,需要将队列设置为空。所以在出队时要进行判断。
    4、front指针是不变的,rear指针是移动的,除了队列为空外,总是指向队尾结点的地址。
    front->next指针也是移动的,每当有元素入队后,指向该结点的地址。
    注:出队时,需要判断出队是否为队尾元素,若是队尾元素的话,要将 rear = front;(顺序不能反)

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值