【数据结构复习03】队列的顺序存储实现及基本操作

队列的顺序存储实现及基本操作

队列的顺序存储类型描述

#define MAXSIZE 10
typedef struct{
	int data[MAXSIZE];	//存放队列元素
	int front,rear;		//队头指针和队尾指针
}SqQueue;

注意事项

  1. 顺序队列的队尾指针有两种情况,一种是将队尾指针指向队尾元素,一种是将队尾指针指向队尾元素的后一位(本文采取这种情况),两种情况在初始化时,前者为:front=0,rear=-1;后者为:front=rear=0。除此外,两种情况在判空、判满、入队、出队、计算队列长度时的操作都不一样。

  2. 在将将队尾指针指向队尾元素的后一位的情况下,计算队列长度有以下公式:
    (rear+MAXSIZE-front)%MAXSIZE

  3. 顺序队列在实现过程中,运用到取模运算,将存储空间在逻辑上变为“环状”,形成循环队列的效果。

  4. 在判满、判空时有不同的几种方法:
    (1).牺牲一个存储单元。本文采用的就是该方法,最大只能存储 MAXSIZE-1 个元素。详见代码描述。
    (2).在定义结构体时,增加一个记录队列长度的 size 变量。初始化时,将size初始化为0,入队操作时+1,出队操作时-1。
    (3).在定义结构体时,增加一个变量tag=0/1,记录最近一次操作是入队操作(tag=1)还是出队操作(tag=0)。这样,虽然判断条件都是(rear==font),但只有删除操作能导致队空,只有增加操作才能导致队满,判断条件变为:

(rear==font && tag==1//判满条件
(rear==font && tag==0//判空条件

源代码

#include<stdio.h>
#define MAXSIZE 10
typedef struct{
	int data[MAXSIZE];
	int front,rear;
}SqQueue; 
void InitQueue(SqQueue &queue){
	queue.front=0;
	queue.rear=0;
}
bool QueueEmpty(SqQueue queue){
	if(queue.front==queue.rear)
		return true;
	return false;
}
bool QueueFull(SqQueue queue){
	if(queue.front==(queue.rear+1)%MAXSIZE) 
		return true;
	return false;
}

bool EnQueue(SqQueue &queue,int e){
	if(QueueFull(queue)){
		return false;
	}
	queue.data[queue.rear]=e;
	queue.rear=(queue.rear+=1)%MAXSIZE;
	return true;
}

bool DeQueue(SqQueue &queue,int &de)
{
	if(QueueEmpty(queue)){
		return false;
	}
	de=queue.data[queue.front];
	queue.front=(queue.front+1)%MAXSIZE;
	return true;
}

bool GetHead(SqQueue queue,int &head)
{
	if(QueueEmpty(queue)){
		return false;
	}
	head=queue.data[queue.front];
	return true;
}

void PrintQueue(SqQueue queue)
{
	if(QueueEmpty(queue))
	{
		printf("队列为空!\n");
	}
	else{
		printf("队列为:");
		while((queue.front+1)%MAXSIZE!=queue.rear)
		{
			printf("\t%d\n",queue.data[queue.front]);
			queue.front++;
		}
		printf("\t%d\n",queue.data[queue.front]);	//这里还要打印一次	
	} 
}

int QueueLen(SqQueue queue){
	return (queue.rear+MAXSIZE-queue.front)%MAXSIZE;
}
int main()
{
	SqQueue queue;
	int head,de;
	
	InitQueue(queue);
	
	for(int i=1;i<11;i++)
	{
		if(!EnQueue(queue,i))
		{
			printf("队列满了\n");
		}
	}
	
	printf("队列的长度:%d\n",QueueLen(queue));
	
	PrintQueue(queue);
	
	if(GetHead(queue,head)){
		printf("对头元素为:%d \n",head);
	}
	
	if(DeQueue(queue,de)){
		printf("出栈的元素是:%d\n",de);		
	} 
	
	if(DeQueue(queue,de)){
		printf("出栈的元素是:%d\n",de);		
	} 
	
	if(GetHead(queue,head)){
		printf("对头元素为:%d \n",head);
	}
	PrintQueue(queue);
	
	printf("队列的长度:%d\n",QueueLen(queue));
			
	return 0;
}

运行结果
在这里插入图片描述
the end…

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是循环队列QUEUE<T>的基本运算算法: 1. 构造函数:用于初始化循环队列。在构造函数中设置队头和队尾指针front和rear均为0,标志tag为false,表示队列为空。 2. 入队操作enqueue(T item):向队列尾部插入元素item。如果队列已满,则抛出队满异常。如果队列非满,则将元素item插入队尾,并将rear指针向后移动一位。 3. 出队操作dequeue():从队列头部取出一个元素并将其删除。如果队列非空,则返回被删除元素的值,并将front指针向后移动一位。如果队列已空,则抛出队空异常。 4. 获取队头元素getFront():返回循环队列的队头元素,并不删除队头元素。如果队列为空,则抛出队空异常。 5. 获取队列元素个数getSize():返回循环队列元素的个数。 6. 判断队列是否为空isEmpty():如果队列为空,则返回true,否则返回false。 7. 判断队列是否已满isFull():如果队列已满,则返回true,否则返回false。 下面是循环队列QUEUE<T>的代码实现: ``` template <typename T> class QUEUE { private: T* data; int front, rear; int capacity; bool tag; // 解决队列满和空的标志 public: // 构造函数 QUEUE(int cap) : front(0), rear(0), capacity(cap + 1), tag(false) { data = new T[capacity]; } // 入队操作 void enqueue(T item) { if (isFull()) throw("Queue is full."); data[rear] = item; rear = (rear + 1) % capacity; if (rear == front) tag = true; } // 出队操作 T dequeue() { if (isEmpty()) throw("Queue is empty."); T item = data[front]; front = (front + 1) % capacity; if (rear == front) tag = false; return item; } // 获取队头元素 T getFront() { if (isEmpty()) throw("Queue is empty."); return data[front]; } // 获取队列元素个数 int getSize() { if (tag) return capacity - 1; else return (rear - front + capacity) % capacity; } // 判断队列是否为空 bool isEmpty() { return front == rear && !tag; } // 判断队列是否已满 bool isFull() { return front == rear && tag; } // 析构函数 ~QUEUE() { delete[] data; } }; ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值