博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(三)数据结构之线性表的简单实现:队列
阅读量:4195 次
发布时间:2019-05-26

本文共 6869 字,大约阅读时间需要 22 分钟。

1、队列的简单定义

队列:具有一定操作约束的线性表;只能在一端插入,在另一端删除;先进先出:First In First Out(FIFO)。

2、队列的顺从存储实现

队列的顺序存储结构通常由一个一维数组和一个记录队列头元素位置的变量front以及一个记录队列尾元素的位置变量rear组成。为了不造成存储空间上的浪费常定义位循环队列。

2.1 基本数据结构

/* 定义队列的基本数据结果 */#define MaxSize		20typedef int ElementType;typedef struct _Queue{	ElementType Data[ MaxSize ];	int rear;	int front;} Queue;

2.2 创建一个空队列

/* 创建一个空队列 */Queue *CreatQueue(){	Queue *Q = (Queue*)malloc(sizeof(Queue));	if(NULL != Q)	{		Q->front = 0;		Q->rear = 0;	}	return Q;}

2.3 插入操作

/* 向循环队列尾部插入一个元素 */void AddQ( Queue *PtrQ, ElementType item){	if ( IsFullQ(PtrQ) )	{		printf("The queue is full!\n");		return;	}	PtrQ->rear = (PtrQ->rear+1)% MaxSize;	PtrQ->Data[PtrQ->rear] = item;}

2.4 删除操作

/* 删除循环队列的队头的元素 */ElementType DeleteQ ( Queue *PtrQ ){	if ( IsEmptyQ(PtrQ) ) 	{		printf("The queue is empty!\n");		return -1;	} 	else 	{		PtrQ->front = (PtrQ->front+1)% MaxSize;		return PtrQ->Data[PtrQ->front];	}}

2.5 完整的示例代码实现

/* 循环队列的顺序存储实现 */#include 
#include
/* 定义队列的基本数据结果 */#define MaxSize 20typedef int ElementType;typedef struct _Queue{ ElementType Data[ MaxSize ]; int rear; int front;} Queue;/* 创建一个空队列 */Queue *CreatQueue(){ Queue *Q = (Queue*)malloc(sizeof(Queue)); if(NULL != Q) { Q->front = 0; Q->rear = 0; } return Q;}/* 消除一个队列 */void DestroyQueue(Queue *PtrQ){ if(NULL != PtrQ) free(PtrQ); PtrQ = NULL;}/* 判断队列是否为空,1为空,0非空 */int IsEmptyQ( Queue *PtrQ ){ return (PtrQ->front == PtrQ->rear);}/* 判断队列是否为满,1为满,0为空 */int IsFullQ( Queue *PtrQ ){ return ((PtrQ->rear+1)%MaxSize == PtrQ->front);}/* 向循环队列尾部插入一个元素 */void AddQ( Queue *PtrQ, ElementType item){ if ( IsFullQ(PtrQ) ) { printf("The queue is full!\n"); return; } PtrQ->rear = (PtrQ->rear+1)% MaxSize; PtrQ->Data[PtrQ->rear] = item;}/* 删除循环队列的队头的元素 */ElementType DeleteQ ( Queue *PtrQ ){ if ( IsEmptyQ(PtrQ) ) { printf("The queue is empty!\n"); return -1; } else { PtrQ->front = (PtrQ->front+1)% MaxSize; return PtrQ->Data[PtrQ->front]; }}/* 遍历一个循环队列 */void TraversalQ( Queue *PtrQ ){ int front, rear, i; if(!IsEmptyQ(PtrQ)) { front = PtrQ->front; rear = PtrQ->rear; for(i = front; i != rear; i = (i+1)%MaxSize) printf("%d ", PtrQ->Data[(i+1)%MaxSize]); printf("\n"); }}/* 程序入口 */int main(){ int i; ElementType temp; Queue *queue = NULL; /* 创建一个循环队列 */ queue = CreatQueue(); if(NULL == queue) { printf("CreatQueue is failed!\n"); return -1; } /* 向循环队列中插入五个元素 */ printf("Input 5 numbers : "); for(i = 0; i < 5; i++) { scanf("%d", &temp); AddQ(queue, temp); } printf("****************************************TraversalQ*******************************\n"); TraversalQ(queue); printf("****************************************AddQ once********************************\n"); printf("Input 1 number : "); scanf("%d", &temp); AddQ(queue, temp); TraversalQ(queue); printf("****************************************DeleteQ twice****************************\n"); DeleteQ(queue); DeleteQ(queue); TraversalQ(queue); DestroyQueue(queue); // 销毁一个循环队列 return 0;}

3、队列的链式存储实现

队列的链式存储结构也可以用一个单链表实现。删除和插入操作分别在链表的两头进行,执行删除的一端是表头,执行插入的一端是表尾。

3.1 基本数据结构实现

/* 定义链式队列的基本数据结构 */typedef int ElementType;typedef struct Node{	ElementType Data;	struct Node *Next;}QNode;typedef struct { 		/* 链队列结构 */	QNode *rear; 		/* 指向队尾结点 */	QNode *front; 		/* 指向队头结点 */} LinkQueue;

3.2 创建一个空队列

/* 创建一个空队列 */LinkQueue *CreatQueue(){	LinkQueue *Q = (LinkQueue *)malloc(sizeof(LinkQueue));	if(NULL != Q)	{		Q->front = NULL;		Q->rear = NULL;	}	return Q;}

3.3 插入操作

/* 向队列尾部插入一个元素 */void AddQ( LinkQueue *PtrQ, ElementType item){	QNode *TempCell = NULL;	TempCell = (QNode*)malloc(sizeof(QNode));	if(NULL == TempCell)	{		printf("Malloc is failed!\n");		return;	}	TempCell->Data = item;	// 赋值给分配的结点	if ( IsEmptyQ(PtrQ) ) 	// 判断队列是否为空	{		PtrQ->rear = PtrQ->front= TempCell;		TempCell->Next = NULL;	}	else	{		PtrQ->rear->Next = TempCell;		TempCell->Next = NULL;		PtrQ->rear = TempCell;	}}

3.4 删除操作

/* 从队列头部删除一个元素 */ElementType DeleteQ ( LinkQueue *PtrQ ){ 	QNode *FrontCell;	ElementType FrontElem;	if ( IsEmptyQ(PtrQ) ) 	{		printf("The link queue is empty!\n"); 		return -1;	}	FrontCell = PtrQ->front;	if ( PtrQ->front == PtrQ->rear) 		/* 若队列只有一个元素 */		PtrQ->front = PtrQ->rear = NULL; 	/* 删除后队列置为空 */	else		PtrQ->front = PtrQ->front->Next;	FrontElem = FrontCell->Data;	free( FrontCell ); 			/* 释放被删除结点空间 */	return FrontElem;}

3.5 完整的示例代码实现

/* 队列的链式存储实现 */#include 
#include
/* 定义链式队列的基本数据结构 */typedef int ElementType;typedef struct Node{ ElementType Data; struct Node *Next;}QNode;typedef struct { /* 链队列结构 */ QNode *rear; /* 指向队尾结点 */ QNode *front; /* 指向队头结点 */} LinkQueue;/* 创建一个空队列 */LinkQueue *CreatQueue(){ LinkQueue *Q = (LinkQueue *)malloc(sizeof(LinkQueue)); if(NULL != Q) { Q->front = NULL; Q->rear = NULL; } return Q;}/* 消除一个队列 */void DestroyQueue(LinkQueue *PtrQ){ while(!IsEmptyQ(PtrQ)) { DeleteQ(PtrQ); } free(PtrQ); PtrQ = NULL;}/* 判断队列是否为空,1为空,0非空 */int IsEmptyQ( LinkQueue *PtrQ ){ return (PtrQ->front == NULL);}/* 向队列尾部插入一个元素 */void AddQ( LinkQueue *PtrQ, ElementType item){ QNode *TempCell = NULL; TempCell = (QNode*)malloc(sizeof(QNode)); if(NULL == TempCell) { printf("Malloc is failed!\n"); return; } TempCell->Data = item; // 赋值给分配的结点 if ( IsEmptyQ(PtrQ) ) // 判断队列是否为空 { PtrQ->rear = PtrQ->front= TempCell; TempCell->Next = NULL; } else { PtrQ->rear->Next = TempCell; TempCell->Next = NULL; PtrQ->rear = TempCell; }}/* 从队列头部删除一个元素 */ElementType DeleteQ ( LinkQueue *PtrQ ){ QNode *FrontCell; ElementType FrontElem; if ( IsEmptyQ(PtrQ) ) { printf("The link queue is empty!\n"); return -1; } FrontCell = PtrQ->front; if ( PtrQ->front == PtrQ->rear) /* 若队列只有一个元素 */ PtrQ->front = PtrQ->rear = NULL; /* 删除后队列置为空 */ else PtrQ->front = PtrQ->front->Next; FrontElem = FrontCell->Data; free( FrontCell ); /* 释放被删除结点空间 */ return FrontElem;}/* 遍历一个队列 */void TraversalQ( LinkQueue *PtrQ ){ QNode *FrontCell; QNode *RearCell; if(!IsEmptyQ(PtrQ)) { FrontCell = PtrQ->front; RearCell = PtrQ->rear; while(FrontCell != RearCell) // 把前面n-1个结点元素值打印出来 { printf("%d ", FrontCell->Data); FrontCell = FrontCell->Next; } printf("%d ", RearCell->Data); // 把最后一个结点元素值打印出来 printf("\n"); }}/* 程序入口 */int main(){ int i; ElementType temp; LinkQueue *queue = NULL; /* 创建一个循环队列 */ queue = CreatQueue(); if(NULL == queue) { printf("CreatQueue is failed!\n"); return -1; } /* 向循环队列中插入五个元素 */ printf("Input 5 numbers : "); for(i = 0; i < 5; i++) { scanf("%d", &temp); AddQ(queue, temp); } printf("****************************************TraversalQ*******************************\n"); TraversalQ(queue); printf("****************************************AddQ once********************************\n"); printf("Input 1 number : "); scanf("%d", &temp); AddQ(queue, temp); TraversalQ(queue); printf("****************************************DeleteQ twice****************************\n"); DeleteQ(queue); DeleteQ(queue); TraversalQ(queue); DestroyQueue(queue); // 销毁一个队列 return 0;}

转载地址:http://qlgoi.baihongyu.com/

你可能感兴趣的文章
Docker 容器化技术介绍(八) 之 Docker 备份与迁移
查看>>
ffmpeg 转码线程数的控制
查看>>
Docker 容器化技术介绍(九) 之 Docker 安装指定版本安装包
查看>>
python 能不能像执行 .exe 文件一样执行 .py 文件呢?
查看>>
Android studio 视频播放(利用Android原生的videoview)
查看>>
“mediacodec” 报错 “No Java virtual machine has been registered”
查看>>
Android Studio 常用系统设置
查看>>
GO语言开发之JSON处理 编码JSON 与 解码JSON
查看>>
爱奇艺 视频编码信息参考
查看>>
x265 视频编码默认参数
查看>>
ffmpeg 视频倍速播放 和 慢速播放
查看>>
x264 高级编码参数
查看>>
ffmpeg 分析两个视频的 psnr 和 ssim
查看>>
Docker 容器化技术介绍(十) 之 Docker 挂载本地目录
查看>>
ffmpeg 实现 视频与gif互转
查看>>
Android 按钮响应点击事件的三种实现方式
查看>>
常见视频格式有哪些?
查看>>
阿里云 人脸识别 测试
查看>>
python图像处理库pillow
查看>>
视频黑屏画面检测 blackframe
查看>>