数据结构(C实现)------- 顺序队列(非循环队列)

和栈相反,队列是一种先进先出的的线性表。它只允许在表的一端进行插入,而在另一端删除元素。这和我们日常生活中的队列是一致的,最早进入队列的元素最早离开。在队列中,允许插入的一端叫做队尾,允许删除的一端则稀烂为队头。

顺序队列,即队列的顺序存储结构。由于队列的队头和队尾的位置均发生变化,因此在队列顺序存储结构中,除了用一组地址连续的存储单元依次存放从队头到队尾的元素之外,还需要附设两个指针front和rear指向队头和队尾元素。

为了操作方便,在此约定:在非空队列中,队头指针front始终指向队头元素,而队尾rear始终指向队尾元素下一个位置。

顺序队列的类型描述:

//顺序队列的类型描述
#define MAXSIZE 100
typedef int ElemType;
typedef struct{
	ElemType *data;
	int front,rear;
}SqQueue;

基本操作:

1. 初始化顺序队列Init_SqQueue(SqQueue* Q):

//初始化顺序队列
void Init_SqQueue(SqQueue* Q){
    Q->data = (SqQueue*)malloc(sizeof(SqQueue) * MAXSIZE);

	Q->front = Q->rear = 0;
}

2. 销毁顺序队列Destroy_SqQueue(SqQueue* Q)

//销毁顺序队列
void Destroy_SqQueue(SqQueue* Q){
	if(Q->data){
		free(Q->data);
		Q->front = Q->rear = 0;
	}
} 

3. 清空顺序队列Clear_SqQueue(SqQueue* Q)

//清空顺序队列
void Clear_SqQueue(SqQueue* Q){
	Q->front = Q->rear = 0;
}

 4. 判断顺序队列是否为空IsEmpty_SqQueue(SqQueue* Q)

//判断顺序队列是否为空
int IsEmpty_SqQueue(SqQueue* Q){
	if(Q->front == Q->rear)
		return 1;
	else{
		return 0;
	}
}

5. 判断顺序队列是否已满iSFull_SqQueue(SqQueue* Q)

//判断顺序队列是否已满
int iSFull_SqQueue(SqQueue* Q){
	if(Q->rear == MAXSIZE)
		return 1;
	else
		return 0;
}

因为没有设置额外的指针,所以这里判断顺序队列是否已满,实际上是假溢出,并不是真的顺序队列满,原因:

随着入队,出队的进行,整个队列会整体向后移动,这样就出现队尾指针已经移动到了最后,再有元素入队就会出现队满,即溢出,而事实上此时队中并未真正的满员,这种现象即称为“假溢出”。

6.  求得顺序队列的长度GetLength_SqQueue(SqQueue* Q)

//求得顺序队列的长度
int GetLength_SqQueue(SqQueue* Q){
	return Q->rear - Q->front;
}

7. 取得顺序队列的的队头GetHead_SqQueue(SqQueue* Q,ElemType *x)

//取得顺序队列的的队头
void GetHead_SqQueue(SqQueue* Q,ElemType *x){
	if(IsEmpty_SqQueue(Q)){
		printf("顺序队列空!\n");
		exit(0);
	}
	else{
		*x = Q->data[Q->front];
	}
}

8. 取得顺序队列的的队尾GetRear_SqQueue(SqQueue* Q,ElemType *x)

//取得顺序队列的的队尾
void GetRear_SqQueue(SqQueue* Q,ElemType *x){
	if(IsEmpty_SqQueue(Q)){
		printf("顺序队列空!\n");
		exit(0);
	}
	else{
		*x = Q->data[Q->rear - 1];
	}
}

9. 入顺序队列En_SqQueue(SqQueue* Q,ElemType x)

//入顺序队列
void En_SqQueue(SqQueue* Q,ElemType x){
	Q->data[Q->rear] = x;
	Q->rear++;
}

10. 出顺序队列De_SqQueue(SqQueue* Q,ElemType *x)

//出顺序队列
void De_SqQueue(SqQueue* Q,ElemType *x){
	if(IsEmpty_SqQueue(Q)){
		printf("顺序队列空!\n");
		exit(0);
	}
	else{
		*x = Q->data[Q->front];
		Q->front++;
	}
}

11. 打印顺序队列Print_SqQueue(SqQueue* Q)

//打印顺序队列
void Print_SqQueue(SqQueue* Q){
	int i = Q->front;
	if(IsEmpty_SqQueue(Q)){
		printf("顺序队列空!\n");
		exit(0);
	}
	else{
		while(i < Q->rear)
			printf("%d\t",Q->data[i++]);
		printf("\n");
	}
}

说明:

以上这种顺序队列会出现“假溢出”,随着入队,出队的进行,整个队列会整体向后移动,这样就出现队尾指针已经移动到了最后,再有元素入队就会出现队满,即溢出,而事实上此时队中并未真正的满员。

为了能充分的利用空间,解决顺序队列的“假溢出”问题,可以采用两种方法:一种是将数据向前移动,让空的存储单元留在队尾;另一种是将顺序队列构造成一个环状的空间,即将队列的数据区data[0....MAXSIZE-1]看成头尾相接的循环结构,使得data[0]接在data[MAXSIZE-1]之后,这就是循环队列。

时间: 2024-12-14 18:40:58

数据结构(C实现)------- 顺序队列(非循环队列)的相关文章

数据结构6_顺序队列(循环队列)

本文实现了顺序队列,与链队列不同的是,顺序队列需要考虑一个问题, 问题情况如下, 解决办法:循环队列,当rear到分配的数组空间末尾时,转到数组头 但是当q.rear==q.front时,又如何区分一种是空队列,一种是满队列的情况呢 这里有两种方案 本次代码实现了第一种方法,同时设置了一个技术变量length,稍加改动便可实现第二个方法 代码如下: #include<iostream>using namespace std;//该顺序队列为循环队列,解决队尾指针达到最大值,队列中有空闲单元,但

二、数据结构之栈、队列、循环队列

二.数据结构之栈.队列.循环队列 顺序栈 Stack.h 结构类型,函数声明: #ifndef _STACK_H_ #define _STACK_H_ typedef int SElementType; ///顺序栈 #define STACK_INIT_SIZE 20 #define STACK_INCREMENT 10 typedef struct { SElementType * base; SElementType * top; int stackSize;///当前栈的大小 }SqSt

c语言描述-链式队列与循环队列

我真的不喜欢写代码 队列的特点 先进先出,即只能从队尾插入元素,从队头删除元素 队列的链式存储结构 #include<stdio.h> #include <stdlib.h> #include<malloc.h> typedef struct QNode { int date; struct QNode *next; }QNode ,*QueuePtr; typedef struct { int size; //记录队列长度 QueuePtr front; //头指针

队列与循环队列

复习一下队列与循环队列的实现(C语言) 1.单链队列: 1 typedef struct QNode{ //若不写typedef,在C中每次定义QNode需要在前面加上struct,而C++不必 2 QElemType data; 3 struct QNode *next; 4 }QNode,*QueuePtr; 5 6 typedef struct{ //若不写结构体名,则需要加上typedef 7 QueuePtr front; 8 QueuePtr rear; 9 }LinkQueue;

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

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

数据结构基础(5)--队列和循环队列详解--静态方式

队列的具体应用: 所有和事件有关的操作都有队列的影子. (例如操作系统认为先进来的先处理) 定义: 一种可是实现"先进先出"的存储结构 分类: 链式队列:用链表实现 静态队列:用数组实现 静态队列通常都必须是循环队列,为了减少 内存浪费. 循环队列 : 1.静态队列为什么必须是循环队列 如果用传统意义的数组实现队列,无论入队还是出队,rear和front指针只能+不能-: 比 F元素下标小的的数组元素下标就浪费了. 循环队列怎么用呢? 当出现这种情况时,如果仍然需要插入元素,那么f指向

数据结构——队列及循环队列

说明:严蔚敏的<数据结构>(C语言版)学习笔记,记录一下,以备后面查看. #include <stdio.h> #include <stdlib.h> #define OK 1; #define ERROR -1; typedef int QElemType; typedef int Status; //定义队列节点 typedef struct QNode{ QElemType data; struct QNode *next; }QNode, *QueuePtr;

队列:顺序队列和循环队列

和栈的先进后出不同,队列的形式是先进先出,队列的想法来自于生活中排队的策略, 顾客在付款结账的时候,按照到来的先后顺序排队结账.先来的顾客先结账,后来的顾客后结账. 队列有两种实现形式:1 顺序表实现 2 循环顺序表 首先来看下顺序表的实现,在python中,队列的实现用list来写十分的方便.实现方式如下: class line_queue(): def __init__(self): self._elem=[] def push(self,elem): self._elem.append(e

数据结构实验4:C++实现循环队列

实验4 4.1 实验目的 熟练掌握队列的顺序存储结构和链式存储结构. 熟练掌握队列的有关算法设计,并在循环顺序队列和链队列上实现. 根据具体给定的需求,合理设计并实现相关结构和算法. 4.2 实验要求 4.2.1 循环顺序队列的实验要求 循环顺序队列结构和运算定义,算法的实现以库文件方式实现,不得在测试主程序中直接实现: 实验程序有较好可读性,各运算和变量的命名直观易懂,符合软件工程要求: 程序有适当的注释. 4.3 实验任务 4.3.1 循环顺序队列实验任务 编写算法实现下列问题的求解. <1