数据结构--队列实现(顺序队列和链队列)与C++模板

数据结构--队列实现(顺序队列和链队列)与C++模板

一、顺序队列

队列的顺序存储结构称为顺序队列,顺序队列实际上是运算受限的顺序表。

①和顺序表一样,顺序队列用一个向量空间来存放当前队列中的元素。

②由于队列的队头和队尾的位置是变化的,设置两个指针front和rear分别指示队头元素和队尾元素在向量空间中的位置,它们的初值在队列初始化时均应置为0。

注意:

①当头尾指针相等时,队列为空。

②在非空队列里,队头指针始终指向队头元素,尾指针始终指向队尾元素的下一位置。(所以以下循环顺序队列中当队尾指针指向了队头指针的前一位就表示队列已经满了)

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

#define OK   1
#define FAIL 0

//最大队列长度  循环队列的大小减1 为了区分队空与队满的判断
#define QUEUE_MAX_SIZE   (10+1) 

typedef int QElemType;

//基于数组
typedef struct
{
	QElemType *queue;
	int front;   //表示当前队列的头
	int rear;    //表示队尾 插入数据的位置(没有数据) 

}MY_QUEUE_T;

int my_atoi(char *str, int m)
{
	int i;
	int num = 0;

	if(!str) return FAIL;

	while(str[i] != '\0')
	{
		if(!isdigit(str[i]))
			return FAIL;
		num = num*10 + str[i] - '0';
		i++;
	}

	return OK;
}

//初始化队列
void Queue_Init(MY_QUEUE_T *q)
{
	q->queue = (QElemType *)malloc(QUEUE_MAX_SIZE * sizeof(QElemType));
	q->front = 0;
	q->rear = 0;

	if(!q->queue)
		exit(-1);
	else
		printf("Queue Init OK!\n");
} 

//队列空判断
int Queue_Empty(MY_QUEUE_T *q)
{
	if(q->front == q->rear)
	{
		printf("The queue is empty!\n");
		return OK;
	}
	else
		return FAIL;
}

//队列满判断
int Queue_Full(MY_QUEUE_T *q)
{
	if((q->rear + 1)%QUEUE_MAX_SIZE == q->front)
	{
		printf("The queue is Full!\n");
		return OK;
	}
	else
		return FAIL;
}

//取队头元素 并将队头元素出队
int Queue_Pop(MY_QUEUE_T *q, int *e)
{
	if(Queue_Empty(q))
		return FAIL;

	*e = q->queue[q->front];
	q->front = (q->front + 1) % QUEUE_MAX_SIZE;

	return OK;
}

//队尾插入元素元素  返回插入是否成功
int Queue_Push(MY_QUEUE_T *q,int <span style="font-family: Arial, Helvetica, sans-serif;">e)</span>
{
	if(Queue_Full(q))   //队列满 则返回插入失败
		return FAIL;

	q->queue[q->rear] = e;
	q->rear = (q->rear + 1) % QUEUE_MAX_SIZE;
	printf("Insert %d at the queue position %d!\n",e,q->rear);

	return OK;
}

//打印队列元素
void Queue_Print(MY_QUEUE_T *q)
{
	int i;

	if(!Queue_Empty(q))
	{
		printf("The queue is:");
		for(i=q->front; i!=q->rear; i++)
		{
			printf(" %d",q->queue[i]);
			if((i+1) % QUEUE_MAX_SIZE == 0)
				i = -1;    //for 循环自动+1
		}
		printf("\n");
	}
}

int  main(int argc, char **argv)
{
	MY_QUEUE_T my_queue;
	char *str;
	int num;

	Queue_Init(&my_queue);
	printf("Please input action,'P' or 'q'\n");

	while(scanf("%s",str)!=EOF)
	{
		if(*(str) == 'p' || *(str) == 'P')
		{
			printf("Please input insert num:");
			scanf("%d",&num);

			if(!Queue_Push(&my_queue,num))
			{
				printf("Queue Push Fail!\n");
			}
		}
		else if(*(str) == 'q' || *(str) == 'Q')
		{
			if(Queue_Pop(&my_queue, &num))
			{
				printf("Get the queue head :%d\n",num);
			}
		}

		Queue_Print(&my_queue);
		printf("Please input action,'P' or 'q'\n");
	}

	return 0;
}

二、链队列

队列的链式存储结构简称为链队列。它是限制仅在表头删除和表尾插入的单链表。

注意:

     增加指向链表上的最后一个结点的尾指针,便于在表尾做插入操作。

 链队列示意图见上图,图中Q为ListNode型的指针。

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

#define OK   1
#define FAIL 0

//用链表队列长度无限制 

typedef int QElemType;

//定义链表
typedef struct ListNode
{
	QElemType data;
	struct ListNode *next;

}ListNode;

typedef ListNode  *PtrList;
ListNode Head;

//基于链表的队列模型
typedef struct
{
	PtrList front;
	PtrList rear; 

}MY_QUEUE_T;

//初始化队列
void Queue_Init(MY_QUEUE_T *q)
{
	q->front = q->rear = (PtrList)malloc(sizeof(ListNode));

	q->front->next = NULL;

	if(!q->front)
		exit(-1);
	else
		printf("Queue Init OK!\n");
} 

//队列空判断
int Queue_Empty(MY_QUEUE_T *q)
{
	if(q->front == q->rear)
	{
		printf("The queue is empty!\n");
		return OK;
	}
	else
		return FAIL;
}

//取队头元素 并将队头元素出队
int Queue_Pop(MY_QUEUE_T *q, QElemType *e)
{
	PtrList p;

	if(Queue_Empty(q))
		return FAIL;

	p = q->front;         //获取队列头结点  p用于释放出队后的结点空间
	*e = p->data;         //获取头结点数据
	q->front = p->next;   //移动队列头指针到下一个结点 

	free(p);
	return OK;
}

//队尾插入元素元素  返回插入是否成功
int Queue_Push(MY_QUEUE_T *q, QElemType e)
{
	PtrList new_node = (PtrList)malloc(sizeof(ListNode));
	new_node->next = NULL; 

	if(!new_node) return FAIL;  //申请内存失败 插入不成功 

	q->rear->data = e;         //插入数据到当前结点
	q->rear->next = new_node;  //当前结点next指向新申请的结点
	q->rear = new_node;        //队列尾指针指向新申请的结点
	printf("Insert %d at the queue!\n",e);

	return OK;
}

//打印队列元素
void Queue_Print(MY_QUEUE_T *q)
{
	PtrList p;
	p = q->front;

	if(!Queue_Empty(q))
	{
		printf("The queue is:");
		while(p != q->rear)
		{
			printf(" %d",p->data);
			p = p->next;
		}
		printf("\n");
	}
}

int  main(int argc, char **argv)
{
	MY_QUEUE_T my_queue;
	char *str;
	int num;

	Queue_Init(&my_queue);
	printf("Please input action,'P' or 'q'\n");

	while(scanf("%s",str)!=EOF)
	{
		if(*(str) == 'p' || *(str) == 'P')
		{
			printf("Please input insert num:");
			scanf("%d",&num);

			if(!Queue_Push(&my_queue,num))
			{
				printf("Queue Push Fail!\n");
			}
		}
		else if(*(str) == 'q' || *(str) == 'Q')
		{
			if(Queue_Pop(&my_queue, &num))
			{
				printf("Get the queue head :%d\n",num);
			}
		}

		Queue_Print(&my_queue);
		printf("Please input action,'P' or 'q'\n");
	}

	return 0;
}

三、C++队列模板

头文件 #include <queue>

时间: 2024-10-10 09:03:15

数据结构--队列实现(顺序队列和链队列)与C++模板的相关文章

数据结构(二):链表、链队列

上一篇博文中主要总结线性表的顺序存储结构实现.比方顺序表.顺序队列和顺序栈.详细能够參考上篇博文 http://blog.csdn.net/lg1259156776/article/details/46993591 以下要进行学习和总结的是线性表的链式存储结构实现,比方链表和链队列. 顺序存储结构的优缺点 长处是逻辑相邻,物理相邻,可随机存取任一元素,存储空间使用紧凑:缺点是插入.删除操作须要移动大量的元素.平均移动n/2,预先分配空间需依照最大空间分配.利用不充分(C++ STL模板库中实现的

顺序栈和链队列

停车场管理 设停车场是一个可停放n辆车的狭长通道,且只有一个大门可供汽车进出.汽车在停车场内按车辆到达时间的先后顺序,依次由北向南排列(大门在最南端,最先到达的第一辆车停放在车场的最北段),若停车厂内已停满n辆汽车,则后来的汽车只能在门外的便道上等候,一旦有车开走,则排在便道上的第一辆车迹可开入:停车场内某辆车要离开时,在它之后进入的车连必须先退出车厂为它让路,待该车辆开出大门外,其他车辆再按原次序进入车场,每辆停放在车场的车在它离开停车时必须按它停留的时间长短缴纳费用.编写按上述要求进行管理的

数据结构Java实现07----队列:顺序队列&amp;顺序循环队列、链式队列、顺序优先队列

数据结构Java实现07----队列:顺序队列&顺序循环队列.链式队列.顺序优先队列 一.队列的概念: 队列(简称作队,Queue)也是一种特殊的线性表,队列的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置插入和删除,而队列只允许在其一端进行插入操作在其另一端进行删除操作. 队列中允许进行插入操作的一端称为队尾,允许进行删除操作的一端称为队头.队列的插入操作通常称作入队列,队列的删除操作通常称作出队列. 下图是一个依次向队列中插入数据元素a0,a1,...,an-

数据结构——链队列实现二叉树的层次遍历

在二叉树的遍历这篇博客中https://www.cnblogs.com/wkfvawl/p/9901462.html 对于二叉树的层次遍历我只是给出了基于C++ STL的代码,这里我使用数据结构的链表,构建一个链队列来实现.这也算是我第一次使用链队列来完成某个任务,链队列代码还是来自课本,因为之前使用C++ STL时,queue中的某些函数是有返回值的列如Q.front(),而有些却没有返回值像Q.push(p),Q.pop(),就连有没有参数也是不同的,在这里我没有改动课本上的代码来适应自己的

数据结构(C实现)------- 链队列

链队列,即队列的链式存储结构,它是仅在表头删除和表尾插入的单链表,因此一个链队列需要设置两个分别指示队头元素和队尾元素的指针,为了操作方便,给链队列添加一个头结点,并令队头指针指向头结点,由此,空的链队列的判断条件就是队头指针和队尾指针均指向头结点. 链队列的类型描述: //链队列类型描述 typedef int QElemType; typedef struct node{ QElemType data; struct node *next; }QNode,*QueuePtr; typedef

补完链队列的其它常见操作

返回队头元素 若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR.大发888娱乐城 /* 若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR */ Status GetHead(LinkQueue Q, QElemType *e) { QueuePtr p; if(Q.front==Q.rear) return ERROR; p=Q.front->next; *e=p->data; return OK; } 求队列的长度 求链队列的长度,用一个工作指针遍历队列然

数据结构_线性表_顺序队列_循环队列_链队列

个位看官,由于队列操作相对简单,我啥也不多说,直接上代码,欢迎验证!!! #pragma mark --abstract //队列(queue)是只允许在表的一端进行插入,在表的另一端进行删除的线性表,允许插入的一端称为队尾(rear) //允许删除的一端叫做队头(font),不含元素的队列称为空队列 //队列的特点是先进先出(FIFO线性表) #pragma mark --分类 //1.队列的顺序存储结构称为顺序队列(sequential queue),他是由存放队列的一维数组和分别指向队头和

数据结构-循环顺序队列&amp;链队列

队列接口实现: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _003_队列 { interface IQueue<T> { int Count { get; } int GetLength(); bool IsEmpty(); void Clear(); void Enqueue(T it

数据结构:C_队列的顺序表示和实现

数据结构:队列的顺序表示和实现(C语言版) 1.写在前面 附:C_队列的链式表示和描述 对于队列最好的方法是使用链表实现,因为对于数组来说,队列可能会出现下面这种情况: 如图所示,不可以继续添加元素,否则会造成数组越界而遭致程序出错.然而此时又不应该扩充数组,因为还有大量实际空间未被占用. 此时我们应该如何解决这个问题呢?我们将其实现为循环队列. 理解: 何谓循环队列?如下图 图中有两个指针(其实就是两个整数型变量,因为在这里有指示作用,所以这里理解为指针)front.rear,一个指示队头,一