数据结构之队列

队列的链式存储表示

队列的链式存储结构简称链队列,它是限制仅在表头进行删除操作和表尾进行插入操作的单链表。
需要两类不同的结点:数据元素结点,队列的队首指针和队尾指针的结点。

数据元素结点类型定义

typedef struct Qnode {
	ElemType	data;
	struct Qnode* next;
}QNode;

指针结点类型定义

typedef struct link_queue {
	QNode* front, * rear;
}Link_Queue;

链队列初始化

Link_Queue* Init_LinkQueue(void) {
	Link_Queue* Q;	QNode* p;
	p = (QNode*)malloc(sizeof(QNode));	/* 开辟头结点 */
	p->next = NULL;
	Q = (Link_Queue*)malloc(sizeof(Link_Queue));
	/* 开辟链队的指针结点 */
	Q->front = Q->rear = p;
	return(Q);
}

链队列的入队操作

Status Insert_CirQueue(Link_Queue* Q, ElemType e) {
	/* 将数据元素e插入到链队列Q的队尾 */
	QNode* New_node;
	New_node = (QNode*)malloc(sizeof(QNode));
	if (!New_node)	return ERROR;	/* 申请新结点失败,返回错误标志 */
	New_node->data = e;	/* 新结点数据域赋值 */
	New_node->next = NULL;	/* 形成新结点 */
	Q->rear->next = New_node;	Q->rear = New_node;	/* 新结点插入到队尾 */
	return OK;
}

链队列的出队操作

Status Delete_LinkQueue(Link_Queue* Q, ElemType* x) {
	/* 将头结点删除,并将该结点的值赋值给 *x */
	QNode* del_p;
	if (Q->front == Q->rear)	return ERROR;	/* 队空 */
	del_p = Q->front->next;	/* 取队首结点 */
	(*x) = del_p->data;
	Q->front->next = del_p->next;	/* 修改队首指针 */
	if (del_p == Q->rear)	Q->rear = Q->front;
	/* 当队列只有一个结点时应防止丢失队尾指针 */
	free(del_p);
	return OK;
}

链队列的头结点元素提取

Status Get_LinkQueue(Link_Queue* Q, ElemType* x) {
	/* 将头结点直接该结点的值赋值给 *x */
	if (Q->front == Q->rear)	return ERROR;
	(*x) = Q->front->next->data;
	return OK;
}

链队列的撤销

Status Free_LinkQueue(Link_Queue* Q) {
	//QNode* delete_node;
	//if (Q->front == Q->rear)	return ERROR;
	//while (Q->front->next != NULL) {
	//	printf("\nhello");
	//	QNode* delete_node = Q->front->next;
	//	printf("%d", delete_node->data);
	//	Q->front->next = delete_node->next;
	//	free(delete_node);
	//}
	//return OK;
	while (Q->front!=NULL) {
		Q->rear = Q->front->next;	/* 令尾指针指向队列的第一个结点 */
		free(Q->front);	/* 每次释放一个节点 */
		/* 第一次是头结点,以后是元素结点 */
		Q->front = Q->rear;
	}
	return OK;
}

打印链队列中元素

Status Printf_LinkQueue(Link_Queue* Q) {
	QNode* print_node;
	if (Q->front == Q->rear)	return ERROR;	/* 队空 */
	print_node = Q->front;	/* 取队首结点 */
	while (print_node!= Q->rear) {
		print_node = print_node->next;
		printf("%d ", print_node->data);
	}
	return OK;
}

全部代码

#define _CRT_SECURE_NO_WARNINGS

#include "queue.h"
#include <stdlib.h>
#include<stdio.h>
#define ERROR 0
#define OK 1
typedef	int	ElemType;
typedef int Status;
typedef struct Qnode {
	ElemType	data;
	struct Qnode* next;
}QNode;
typedef struct link_queue {
	QNode* front, * rear;
}Link_Queue;

Link_Queue* Init_LinkQueue(void) {
	Link_Queue* Q;	QNode* p;
	p = (QNode*)malloc(sizeof(QNode));	/* 开辟头结点 */
	p->next = NULL;
	Q = (Link_Queue*)malloc(sizeof(Link_Queue));
	/* 开辟链队的指针结点 */
	Q->front = Q->rear = p;
	return(Q);
}
Status Insert_CirQueue(Link_Queue* Q, ElemType e) {
	/* 将数据元素e插入到链队列Q的队尾 */
	QNode* New_node;
	New_node = (QNode*)malloc(sizeof(QNode));
	if (!New_node)	return ERROR;	/* 申请新结点失败,返回错误标志 */
	New_node->data = e;	/* 新结点数据域赋值 */
	New_node->next = NULL;	/* 形成新结点 */
	Q->rear->next = New_node;	Q->rear = New_node;	/* 新结点插入到队尾 */
	return OK;
}
Status Delete_LinkQueue(Link_Queue* Q, ElemType* x) {
	/* 将头结点删除,并将该结点的值赋值给 *x */
	QNode* del_p;
	if (Q->front == Q->rear)	return ERROR;	/* 队空 */
	del_p = Q->front->next;	/* 取队首结点 */
	(*x) = del_p->data;
	Q->front->next = del_p->next;	/* 修改队首指针 */
	if (del_p == Q->rear)	Q->rear = Q->front;
	/* 当队列只有一个结点时应防止丢失队尾指针 */
	free(del_p);
	return OK;
}
Status Printf_LinkQueue(Link_Queue* Q) {
	QNode* print_node;
	if (Q->front == Q->rear)	return ERROR;	/* 队空 */
	print_node = Q->front;	/* 取队首结点 */
	while (print_node!= Q->rear) {
		print_node = print_node->next;
		printf("%d ", print_node->data);
	}
	return OK;
}
Status Free_LinkQueue(Link_Queue* Q) {
	//QNode* delete_node;
	//if (Q->front == Q->rear)	return ERROR;
	//while (Q->front->next != NULL) {
	//	printf("\nhello");
	//	QNode* delete_node = Q->front->next;
	//	printf("%d", delete_node->data);
	//	Q->front->next = delete_node->next;
	//	free(delete_node);
	//}
	//return OK;
	while (Q->front!=NULL) {
		Q->rear = Q->front->next;	/* 令尾指针指向队列的第一个结点 */
		free(Q->front);	/* 每次释放一个节点 */
		/* 第一次是头结点,以后是元素结点 */
		Q->front = Q->rear;
	}
	return OK;
}
Status Get_LinkQueue(Link_Queue* Q, ElemType* x) {
	/* 将头结点直接该结点的值赋值给 *x */
	if (Q->front == Q->rear)	return ERROR;
	(*x) = Q->front->next->data;
	return OK;
}

int main(void) {
	Link_Queue* link;
	int elem;
	link=Init_LinkQueue();
	/* 插入1 2 3 4 5 6 7 8 */
	Insert_CirQueue(link, 1);
	Insert_CirQueue(link, 2);
	Insert_CirQueue(link, 3);
	Insert_CirQueue(link, 4);
	Insert_CirQueue(link, 5);
	Insert_CirQueue(link, 6);
	Insert_CirQueue(link, 7);
	Insert_CirQueue(link, 8);

	Printf_LinkQueue(link); /* 打印队link */

	Delete_LinkQueue(link, &elem);
	Delete_LinkQueue(link, &elem);
	Delete_LinkQueue(link, &elem);
	Delete_LinkQueue(link, &elem);	/* 删除四次队 link */
	printf("\n");
	Printf_LinkQueue(link);	/* 打印队 */
	Get_LinkQueue(link, &elem);
	printf("\nelem: %d", elem);
	Free_LinkQueue(link);
}

队列的顺序存储结构–循环队列

为充分利用向量空间,克服“假溢出”现象的方法是:将为队列分配的向量空间看成为一个首尾相接的圆环,并将这种队列成为循环队列(Circular Queue)。

结点类型定义

typedef struct seqqueue {
	int element[MAXSIZE];	/* 队列的元素空间 */
	int	front;	/* 头指针指示器 */
	int	rear;	/* 尾指针指示器 */
}SeqQueue;

循环队列的初始化

void InitSeqQueue(SeqQueue* Q) {
	/* 将*Q初始化为一个空的循环队列 */
	Q->front = Q->rear = 0;  
}

入队操作

Status EnterSeqQueue(SeqQueue* Q, int x) {
	/* 将元素x入队 */
	if ((Q->rear + 1) % MAXSIZE == Q->front)	/* 队列已满 */
		return ERROR;
	Q->element[Q->rear] = x;
	Q->rear = (Q->rear + 1) % MAXSIZE;	/* 重新设置队尾指针 */
	return OK;
}

出队操作

Status DeleteSeqQueue(SeqQueue* Q, int* x) {
	if (Q->front == Q->rear)	/* 队列为空 */
		return ERROR;
	(*x) = Q->element[Q->front];
	Q->front = (Q->front + 1) % MAXSIZE;	/* 重新设置队头指针 */
	return OK;	/* 操作成功 */
}

循环队列打印

void PrintfSeqQueue(SeqQueue S) {
	while (S.front != S.rear) {
		printf("%d ", S.element[S.front]);
		S.front = (S.front + 1) % MAXSIZE;
	}
}

循环队列全部代码

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

#define ERROR 0
#define OK 1
#define MAXSIZE	50	/*队列的最大长度*/
typedef	int	ElemType;
typedef int Status;
typedef struct seqqueue {
	int element[MAXSIZE];	/* 队列的元素空间 */
	int	front;	/* 头指针指示器 */
	int	rear;	/* 尾指针指示器 */
}SeqQueue;
void InitSeqQueue(SeqQueue* Q) {
	/* 将*Q初始化为一个空的循环队列 */
	Q->front = Q->rear = 0;  
}
Status EnterSeqQueue(SeqQueue* Q, int x) {
	/* 将元素x入队 */
	if ((Q->rear + 1) % MAXSIZE == Q->front)	/* 队列已满 */
		return ERROR;
	Q->element[Q->rear] = x;
	Q->rear = (Q->rear + 1) % MAXSIZE;	/* 重新设置队尾指针 */
	return OK;
}
Status DeleteSeqQueue(SeqQueue* Q, int* x) {
	if (Q->front == Q->rear)	/* 队列为空 */
		return ERROR;
	(*x) = Q->element[Q->front];
	Q->front = (Q->front + 1) % MAXSIZE;	/* 重新设置队头指针 */
	return OK;	/* 操作成功 */
}
void PrintfSeqQueue(SeqQueue S) {
	while (S.front != S.rear) {
		printf("%d ", S.element[S.front]);
		S.front = (S.front + 1) % MAXSIZE;
	}
}

int main(void) {
	SeqQueue queue;
	int elem;
	InitSeqQueue(&queue);
	EnterSeqQueue(&queue, 1);
	EnterSeqQueue(&queue, 2);
	EnterSeqQueue(&queue, 3);
	EnterSeqQueue(&queue, 4);

	PrintfSeqQueue(queue);

	DeleteSeqQueue(&queue, &elem);
	PrintfSeqQueue(queue);
}
希望坚持把数据结构学完
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值