数据结构———队列

一、队列的概念

首先,队列是一种受限制的顺序表。

因为顺序表可以从一串数据中的任意一个位置进行增减操作。

而队列受限的意思是:队列只能从队头来删除数据(出队),从队尾来增加数据(入队)。

它并不像顺序表那样操作灵活。

二、初始化队列

首先,队列再内存中的存储方式也是连续的一片空间,这和顺序表,栈数据结构的存储方式一样。

不同的是,队列有两个int类型的数据,起到指针的作用,其中一个指向队头,另一个指向队尾。

回顾栈,栈中只有一个int类型的起到指针的作用的数据,始终指向栈尾。

如图所示:

所以,队列的初始化代码如下:

#define MAX 10
typedef struct {
	int data[MAX];
	int front, rear;
}s;

int main()
{
	s s1;
	s1.front = s1.rear = 0;
	return 0;
}

三、队列的入队操作

既然规定队列只能从队尾插入数据,那么在入队操作时,只有int rear 进行一系列操作。

因为初始化队列时,让rear和front都指向了0;此时并没有数据,也可以看成已有数据的后面的又一个位置。所以在进行入队操作时,是让数据插入到rear指向的位置,然后让rear+1往上以一个位置。(这里往上移一个位置会有一些问题)

代码如下:

int main()
{
	s s1;
	s1.front = s1.rear = 0;
	int x = 10;//假设这是要插入的数据
	s1.data[s1.rear] = x;//先赋值
	s1.rear = s1.rear + 1;//再+1
	//也可以写成s1.data[s1.rear++] = x;
	return 0;
}

上面说往上移一位会出现一些问题

看下面图:

如果此时,再想添加一个数据,还是在a[9]的上面添加吗?

肯定不是。

因为我们定义的这片空间最高的位置就是data[9].

这时候我们会有一个取模操作。

代码如下:

int main()
{
	s s1;
	s1.front = s1.rear = 0;
	int x = 10;//假设这是要插入的数据
	s1.data[s1.front] = x;//先赋值
	s1.front = (s1.front + 1)%MAX;//再+1
	//也可以写成s1.data[s1.front++] = x;
	return 0;
}

因为此时rear=9  +1 之后  rear=10   取模之后变成0  ,就指向了最下面一个位置。这时候就构成了闭环。

如下图所示:

 这里的10相当于MAX,为了更好的理解,用MAX=10来举例子

你会发现,10后面的数取模后,就会映射为【0,9】这个范围之内。

这样就相当于一个环形:

 四、队列的出队操作

出队操作是在对头进行一系列操作,所以是front进行一系列的减操作。rear不发生变化

代码如下:

int main()
{
	s s1;
	s1.front = s1.rear = 0;
	//中间进行了一系列入队,出队操作。
	s1.front = s1.front + 1;
	return 0;
}

这里再逻辑上让头指针+1,往后移一位,实际上其位置上的数据并没有删除。

五、队列的判空、满

在初始化时,我们创建了一个空的队列,此时front和rear豆等于0.

那么我们是否可以把条件 front==rear作为判空条件呢?

其实这里也存在一些问题。

我们思考一种极端情况:

a[0]到a[8]都有数据,此时我们再插入一个数据到a[9]。

这时候我们根据上面的取模操作构成闭环后  rear=0了  此时rear==front ,但是此时队列并不是空列表。

那么,到底怎么做能表示队列为空呢?

这时候分两种情况:

① 牺牲一个位置,并且 (rear+1)%MAX==front 

如图:

根据上面的极端情况,我们写如下代码:

int main()
{
	s s1;
	s1.front = s1.rear = 0;
	//中间进行了一系列入队,出队操作。
	if ((s1.rear + 1) % MAX == s1.front)
	{
		;//此时判断已满,退出入队操作
	}
	return 0;
}

②不牺牲位置,增加一个变量,让判断条件更加灵活

这里添加一个变量又分为两种情况:

第一种:添加的变量用来表示数据的个数

代码如下:

typedef struct {
	int data[MAX];
	int front, rear;
	int num;
}s;

int main()
{
	s s1;
	//进行入队操作
	s1.num++;
	//进行出队操作
	s1.num--;
	//判断是否空满
	if (s1.num == 10)
	{
		//判断队列已满
	}
	return 0;
}

第二种:添加的变量用来表示最后一次操作是入队操作还是出队操作

因为只有入队操作才可能导致队列为满,只有出队操作才可能导致队列为空。

当变量表示入队时,在这种条件下,如果数据的数量==10,则队列为满

当变量表示出队时,在这种条件下,如果数据的数量==0  ,则队列为空

那么这时候怎么表示数据的个数呢?

还是用num++  num--吗?

这时候有一个固定公式:

(rear+MAX-front)%MAX ==数据的个数

代码如下:

typedef struct {
	int data[MAX];
	int front, rear;
	int tag;
}s;

int main()
{
	s s1;
	s1.tag = 0;//0 代表出队操作
	//下面进行入队操作
	s1.tag = 1;
	if (s1.tag == 1 && (s1.rear + MAX - s1.front) % MAX == 10)
	{
		;//此时为满
	}
    //下面进行出队操作
	if (s1.tag = 0 && (s1.rear + MAX - s1.front) % MAX == 0)
	{
		;//此时为空
	}
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值