严蔚敏版数据结构——队列(顺序表表示)

队列有两种表示方式,我们先看顺序表示:

代码中的rear(尾指针)与front(头指针)都是int 型的,它的作用就是做数组下标,我们习惯称它为指针,这里应该注意它不是指针类型。头指针始终指向队列头元素,尾指针始终指向队尾元素的下一个位置。

由于增加元素rear加一,删除元素front也加一,没错都是加一。就像一排10个座位,一开始只有前面三个座位有人,但我们的规则是:只能前面的同学离开,后来的同学只能坐后面。这样的话过了一会儿会发现同学们都坐在后面,而前面的座位没人坐,这就尴尬了——明明前面有位子却不能坐,班长说已经满了,再坐后面就没座位了(溢出)。我们肯定会质疑这个规则有毛病,但是班长说把10个座位围起来形成一个圆圈,第10号座位后面跟着第1号。哎!这个办法不错,既没有违背规则,又没有浪费位子。这就可以用“模”运算解决循环问题,即满了10我们就让他变为0,其他是多少就是多少。当增加一个元素时rear=(rear+1)%10,(注意数组下标0开始,扭转思维)。

下面我们来思考一个问题:

  【1】 当一个人都没有的时候,front==rear;当全部坐满的时候 rear==front;由此可见,循环队列不能以头尾指针是否相同来判别队列是否为空。这里我们采用空出一个位置的方法来标记是否队满:

记住下面两点(很重要):

队空的条件:front==rear;

队满的条件:(rear+1)% MAXSIZE==front;

接下来还是看代码实现来的爽快:

#include
#include 
#define OK 1
#define ERROR 0
#define MAXSIZE 20

typedef struct
{
	int data;
	
}MyType;

typedef struct
{
	MyType *base;
	//注意这两个标记不是指针类型,属于数组下标。但我们习惯叫它指针; 
	int front; 
	int rear;
}SqQueue;

//---------------初始化队列----------------
int InitQueue(SqQueue & Q)
{
	//构造一个空队列
	Q.base=new MyType[MAXSIZE];
	if(Q.base==NULL)
	return ERROR;
	
	Q.front=Q.rear=0;
	return OK;
} 
//--------------求队列的长度---------------- 
int QueueLength(SqQueue Q)
{
    //因为是循环队列,所以rear可以比front小,一减就是负数,其绝对值也就是空位置的大小
    //MAXSIZE减去空位置就是长度

	return  (MAXSIZE+Q.rear-Q.front)%MAXSIZE;
} 
//--------------入队操作---------------
int EnQueue(SqQueue &Q,MyType e)
{
    //先判断满了没
	if((Q.rear+1)%MAXSIZE==Q.front)
		return ERROR;
	Q.base[Q.rear].data=e.data;
	Q.rear=(Q.rear+1)%MAXSIZE;
	return OK; 
} 
//-------------出队操作-----------------
int DeQueue(SqQueue &Q,MyType &e)
{
    //先判断是不是空队列
	if(Q.front==Q.rear)
	return ERROR;
	e.data=Q.base[Q.front].data;
	Q.front=(Q.front+1)%MAXSIZE;
	return OK; 
} 
//--------------取循环队列对头元素----------
MyType GetHead(SqQueue Q)
{
    //不是空就这样干
	if(Q.front!=Q.rear)
	return Q.base[Q.front];
}
//-------------打印出来看看-------------
void Print(SqQueue Q)
{
	int i;
	for(i=Q.front;i

运行结果如下:

严蔚敏版数据结构——队列(顺序表表示)_第1张图片

 

你可能感兴趣的:(数据结构)